我在版本 11 中使用 AutoMapper 映射两个类时遇到一些问题。目标类具有索引器属性,这会导致问题。
自 Automapper 11 起,索引器属性不再自动被忽略。
出于测试目的,我使用了三个类:
public class Source {}
public class Target {
public float this[int key]
{
get
{
return 0;
}
set
{
}
}
}
public class MapperProfile: Profile
{
public MapperProfile()
{
CreateMap<Source, Target>();
}
}
在启动过程中,我调用
mapper.ConfigurationProvider.AssertConfigurationIsValid()
来验证配置。由于未映射的 Item 属性,此操作失败。
虽然可以使用 忽略以 Item
开头的所有属性this.AddGlobalIgnore("Item")
在配置文件中,我不想使用这种通用方法来忽略它,特别是因为第一个参数被标记为 propertyNameStartingWith - 这对我来说意味着其他属性,例如 ItemWithSuffix 也可能被忽略。
我尝试采用的另一个策略是对属性使用显式忽略。由于编译器错误,使用表达式符号失败:
CreateMap<Source, Target>()
.ForMember(dest => dest[], opt => opt.Ignore())
.ReverseMap();
向表达式添加任意索引失败并出现另一个错误,因此这似乎也不是一个可行的解决方案:
CreateMap<Source, Target>()
.ForMember(dest => dest[0], opt => opt.Ignore())
.ReverseMap();
在这种情况下,错误指出,我们可能无法映射到子属性。
使用成员名称语法时,会出现一些不同的错误。
CreateMap<Source, Target>()
.ForMember("Item", opt => opt.Ignore())
.ReverseMap();
在这种情况下,它会失败并显示以下消息:
为调用方法“Double get_Item(Int32)”(参数“property”)提供的参数数量不正确
使用
[]
或 Item[]
失败,并显示缺少属性通知。
我采用的最后一个策略是使用 ForAllMembers 调用。这成功了,但是,我想知道是否有更好的解决方案来处理此逻辑,允许对单个成员使用特定的映射逻辑。
CreateMap<Source, Target>()
.ForAllMembers(x =>
{
if (x.DestinationMember.Name == "Item")
{
x.Ignore();
}
});
所以我刚才就面临这个问题。我正在使用 .NET 8 和 Automapper 13。
在这个项目的类中,我经常有多个索引属性,并且具有不同的签名。一种通常采用字符串键,一种可能有整数,但它们通常使用枚举。这并不重要——为什么——但要点是一个类可以有多个索引器;它们全部被命名为“物品”。
我只是希望 Automapper 忽略索引器,因为我经常将它们设置为获取封装属性(甚至可能是嵌套类)的快捷方式。
但是,将“Item”添加到全局忽略似乎没有任何效果;至少,它没有解决问题...
这做到了..
new MapperConfiguration(cfg => {
// array of types with indexers to use in automapper
Type[] types = [typeof(HasIndexers), typeof(AnotherWithIndexers)];
// Get list of reflected PropertyTypes to ignore
var indexers = types.SelectMany(x =>
x.GetProperties().Where(y => y.Name == "Item")).ToList();
indexers.ForEach(x => cfg.ShouldMapProperty = x => false);
// Continue with your configuration
cfg.AddProfile<ProfileType>();
}).CreateMapper();