有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
当前回答
The only infromation about ignoring many of members is this thread - http://groups.google.com/group/automapper-users/browse_thread/thread/9928ce9f2ffa641f . I think you can use the trick used in ProvidingCommonBaseClassConfiguration to ignore common properties for similar classes. And there is no information about the "Ignore the rest" functionality. I've looked at the code before and it seems to me that will be very and very hard to add such functionality. Also you can try to use some attribute and mark with it ignored properties and add some generic/common code to ignore all marked properties.
其他回答
我已经能够做到这一点的方式如下:
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。
这似乎是一个老问题,但我想我会把我的答案贴出来给那些长得像我的人。
我使用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());
这是我编写的一个扩展方法,它忽略目标上所有不存在的属性。不确定它是否仍然有用,因为这个问题已经存在两年多了,但我遇到了同样的问题,必须添加大量手动忽略调用。
public static IMappingExpression<TSource, TDestination> IgnoreAllNonExisting<TSource, TDestination>
(this IMappingExpression<TSource, TDestination> expression)
{
var flags = BindingFlags.Public | BindingFlags.Instance;
var sourceType = typeof (TSource);
var destinationProperties = typeof (TDestination).GetProperties(flags);
foreach (var property in destinationProperties)
{
if (sourceType.GetProperty(property.Name, flags) == null)
{
expression.ForMember(property.Name, opt => opt.Ignore());
}
}
return expression;
}
用法:
Mapper.CreateMap<SourceType, DestinationType>()
.IgnoreAllNonExisting();
更新:显然,如果您有自定义映射,这不能正确工作,因为它会覆盖它们。我想如果先调用IgnoreAllNonExisting,然后再调用自定义映射,它仍然可以工作。
schdr有一个解决方案(作为这个问题的答案),它使用map . getalltypemaps()来找出哪些属性未映射并自动忽略它们。在我看来这是个更可靠的解决方案。
对于那些使用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字段。
对于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字段的输出对象将被解析,所有其他将被跳过。工作就像一个魅力,似乎我们不需要任何棘手的扩展了!