有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
当前回答
我更新了Robert Schroeder对AutoMapper 4.2的答案。对于非静态映射器配置,我们不能使用mapper . getalltypemaps(),但表达式有一个对所需的TypeMap的引用:
public static IMappingExpression<TSource, TDestination>
IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
foreach (var property in expression.TypeMap.GetUnmappedPropertyNames())
{
expression.ForMember(property, opt => opt.Ignore());
}
return expression;
}
其他回答
对于Automapper 5.0,为了跳过所有未映射的属性,你只需要放
.ForAllOtherMembers(x=>x.Ignore());
在你资料的最后。
例如:
internal class AccountInfoEntityToAccountDtoProfile : Profile
{
public AccountInfoEntityToAccountDtoProfile()
{
CreateMap<AccountInfoEntity, AccountDto>()
.ForMember(d => d.Id, e => e.MapFrom(s => s.BankAcctInfo.BankAcctFrom.AcctId))
.ForAllOtherMembers(x=>x.Ignore());
}
}
在这种情况下,只有Id字段的输出对象将被解析,所有其他将被跳过。工作就像一个魅力,似乎我们不需要任何棘手的扩展了!
默认情况下,AutoMapper使用目标类型来验证成员,但您可以通过使用MemberList跳过验证。没有选择。
var configuration = new MapperConfiguration(cfg =>
cfg.CreateMap<Source2, Destination2>(MemberList.None);
);
你可以在这里找到参考资料
我已经更新了Can Gencer的扩展,不覆盖任何现有的地图。
public static IMappingExpression<TSource, TDestination>
IgnoreAllNonExisting<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var sourceType = typeof (TSource);
var destinationType = typeof (TDestination);
var existingMaps = Mapper.GetAllTypeMaps().First(x => x.SourceType.Equals(sourceType) && x.DestinationType.Equals(destinationType));
foreach (var property in existingMaps.GetUnmappedPropertyNames())
{
expression.ForMember(property, opt => opt.Ignore());
}
return expression;
}
用法:
Mapper.CreateMap<SourceType, DestinationType>()
.ForMember(prop => x.Property, opt => opt.MapFrom(src => src.OtherProperty))
.IgnoreAllNonExisting();
更新:注意,在9.0版本Mapper静态API被删除
更新:这个答案对那些使用最新版本的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来返回,并在该类的更改频率稳定下来后显式地显示这些成员。
这个问题已经问了几年了,但是这个扩展方法对我来说似乎更干净,使用当前版本的AutoMapper (3.2.1):
public static IMappingExpression<TSource, TDestination> IgnoreUnmappedProperties<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var typeMap = Mapper.FindTypeMapFor<TSource, TDestination>();
if (typeMap != null)
{
foreach (var unmappedPropertyName in typeMap.GetUnmappedPropertyNames())
{
expression.ForMember(unmappedPropertyName, opt => opt.Ignore());
}
}
return expression;
}