升级到Automapper v5后,使用.NullSubstitute出现错误

3

我正在将我们的automapper库从3版本更新到5.2.0版本,但是出现了以下错误

System.InvalidOperationException: System.InvalidOperationException: No coercion operator is defined between types 'System.String' and 'System.Int32'

在这行代码中,用于设置两个复杂对象的映射。
cfg.CreateMap<objA, objB>()
.ForAllMembers(config => config.NullSubstitute(string.Empty));

我猜测发生这种情况是因为它不能将int设置为null,现在已经明确表达了这一点,在automapper的v3版本中它只是忽略了它。有人能证实吗?在版本5中,我是否必须显式地映射每个成员类型?

对于此映射,该对象具有整数、布尔值和字符串。是否有一种方法可以告诉它当字符串为空时将其映射为String.Empty并忽略其他类型?

1个回答

3

不幸的是,这是 NullSubstitute 的 AM5 行为,而且 ForAllMembers 不支持过滤并且不提供有关成员映射的任何信息。

作为一种解决方法,我建议使用 ForAllPropertyMaps 方法进行手动“修复”,该方法允许过滤并提供必要的信息:

cfg.ForAllPropertyMaps(
    pm => "".Equals(pm.NullSubstitute) && pm.DestinationPropertyType != typeof(string),
    (pm, m) => pm.NullSubstitute = null
);

这会应用于所有映射的对象吗? - Dan H
是的。在ForAllPropertyMaps中,“All”还能有什么其他意思呢 :) - Ivan Stoev
我误解了你的回答。我以为你的意思是删除 .ForAllMembers 代码并添加 ForAllPropertyMaps 用于一个映射。但你的意思是保留 .ForAllMembers 代码,并添加这个新方法来控制 NullSubstitute 方法适用于每个映射的哪种类型,而不仅仅是特定的一个。无论如何,这让它工作了。谢谢! - Dan H
确实。很抱歉我没有表达清楚,但我以为你是在寻找安全的升级路径,所以上面的代码只是修复了先前由 ForAllMembers 调用设置的无效值。如果你想让所有类型的字符串成员替换为空字符串,则可以从具体映射中删除 ForAlllMembers 调用,并使用单个 cfg.ForAllPropertyMaps(pm => p.NullSubstitute == null && pm.DestinationPropertyType == typeof(string), (pm, m) => pm.NullSubstitute = ""); 将它们全部设置好。 - Ivan Stoev
我曾经遇到过同样的问题。即使使用上述解决方案,也无法阻止可怕的“强制运算符”错误。因此,在尝试了几个小时几乎所有的方法后,我只是删除了NullSubstitute配置,然后它就完美地工作了。也许不是一个“解决方案”,但这可能会帮助某些人。 - Michael K
我的情况是我误解了NullSubstitute的工作原理。根据文档,“替代品被假定为源成员类型,并将通过任何映射/转换后到达目标类型。”我提供的替代品与目标成员兼容,而不是源成员。没有定义转换运算符来将替代品类型更改为源类型,因此我得到了“无强制转换运算符”异常。将替代品类型更改为源类型后,错误消失了。 - Suncat2000

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接