有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
当前回答
我已经能够做到这一点的方式如下:
Mapper.CreateMap<SourceType, DestinationType>().ForAllMembers(opt => opt.Ignore());
Mapper.CreateMap<SourceType, DestinationType>().ForMember(/*Do explicit mapping 1 here*/);
Mapper.CreateMap<SourceType, DestinationType>().ForMember(/*Do explicit mapping 2 here*/);
...
注意:我使用的是AutoMapper v.2.0。
其他回答
更新:这个答案对那些使用最新版本的Automapper不再有用,因为ForAllOtherMembers已经在Automapper 11中被删除了。
AutoMapper的5.0.0-beta-1版本引入了ForAllOtherMembers扩展方法,所以你现在可以这样做:
CreateMap<Source, Destination>()
.ForMember(d => d.Text, o => o.MapFrom(s => s.Name))
.ForMember(d => d.Value, o => o.MapFrom(s => s.Id))
.ForAllOtherMembers(opts => opts.Ignore());
请注意,显式映射每个属性有一个好处,因为当您忘记映射某个属性时,您永远不会遇到映射失败的问题。
也许在您的情况下,明智的做法是忽略所有其他成员,并添加一个TODO来返回,并在该类的更改频率稳定下来后显式地显示这些成员。
在3.3.1版本中,您可以使用IgnoreAllPropertiesWithAnInaccessibleSetter()或IgnoreAllSourcePropertiesWithAnInaccessibleSetter()方法。
默认情况下,AutoMapper使用目标类型来验证成员,但您可以通过使用MemberList跳过验证。没有选择。
var configuration = new MapperConfiguration(cfg =>
cfg.CreateMap<Source2, Destination2>(MemberList.None);
);
你可以在这里找到参考资料
这似乎是一个老问题,但我想我会把我的答案贴出来给那些长得像我的人。
我使用ConstructUsing,对象初始化器加上ForAllMembers忽略例如
Mapper.CreateMap<Source, Target>()
.ConstructUsing(
f =>
new Target
{
PropVal1 = f.PropVal1,
PropObj2 = Map<PropObj2Class>(f.PropObj2),
PropVal4 = f.PropVal4
})
.ForAllMembers(a => a.Ignore());
从AutoMapper 5.0开始,IMappingExpression上的. typemap属性消失了,这意味着4.2解决方案不再有效。我已经创建了一个解决方案,使用原始功能,但具有不同的语法:
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<Src, Dest>();
cfg.IgnoreUnmapped(); // Ignores unmapped properties on all maps
cfg.IgnoreUnmapped<Src, Dest>(); // Ignores unmapped properties on specific map
});
// or add inside a profile
public class MyProfile : Profile
{
this.IgnoreUnmapped();
CreateMap<MyType1, MyType2>();
}
实现:
public static class MapperExtensions
{
private static void IgnoreUnmappedProperties(TypeMap map, IMappingExpression expr)
{
foreach (string propName in map.GetUnmappedPropertyNames())
{
if (map.SourceType.GetProperty(propName) != null)
{
expr.ForSourceMember(propName, opt => opt.Ignore());
}
if (map.DestinationType.GetProperty(propName) != null)
{
expr.ForMember(propName, opt => opt.Ignore());
}
}
}
public static void IgnoreUnmapped(this IProfileExpression profile)
{
profile.ForAllMaps(IgnoreUnmappedProperties);
}
public static void IgnoreUnmapped(this IProfileExpression profile, Func<TypeMap, bool> filter)
{
profile.ForAllMaps((map, expr) =>
{
if (filter(map))
{
IgnoreUnmappedProperties(map, expr);
}
});
}
public static void IgnoreUnmapped(this IProfileExpression profile, Type src, Type dest)
{
profile.IgnoreUnmapped((TypeMap map) => map.SourceType == src && map.DestinationType == dest);
}
public static void IgnoreUnmapped<TSrc, TDest>(this IProfileExpression profile)
{
profile.IgnoreUnmapped(typeof(TSrc), typeof(TDest));
}
}