有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
当前回答
这个问题已经问了几年了,但是这个扩展方法对我来说似乎更干净,使用当前版本的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;
}
其他回答
我知道这是个老问题,但是@jmoerdyk 在你的问题中:
如何在配置文件中的链式creatatemap()表达式中使用它?
你可以像这样在Profile中使用这个答案
this.IgnoreUnmapped();
CreateMap<TSource, Tdestination>(MemberList.Destination)
.ForMember(dest => dest.SomeProp, opt => opt.MapFrom(src => src.OtherProp));
对于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字段的输出对象将被解析,所有其他将被跳过。工作就像一个魅力,似乎我们不需要任何棘手的扩展了!
我已经更新了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被删除
我已经能够做到这一点的方式如下:
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。
对于那些使用4.2.0及以上版本的非静态API的人,可以使用以下扩展方法(在AutoMapperExtensions类中找到):
// from http://stackoverflow.com/questions/954480/automapper-ignore-the-rest/6474397#6474397
public static IMappingExpression IgnoreAllNonExisting(this IMappingExpression expression)
{
foreach(var property in expression.TypeMap.GetUnmappedPropertyNames())
{
expression.ForMember(property, opt => opt.Ignore());
}
return expression;
}
这里重要的是,一旦删除了静态API,像Mapper这样的代码。FindTypeMapFor将不再工作,因此要使用表达式。TypeMap字段。