有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?
我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。
当前回答
版本12 这是一个非常糟糕的代码,但它解决了紧急工作。
CreateMap<RepairPutRequest, Repair>(MemberList.None)
.ForAbdusselamMember(x => x.ClosedLostTimeId, y => y.MapFrom(z => z.ClosedLostTimeId))
.ForAbdusselamMember(x => x.Explanation, y => y.MapFrom(z => z.Explanation)).IgnoreUnmapped()
;
public static class MappingExtensions
{
public static Dictionary<string, List<string>> list = new Dictionary<string, List<string>>();
public static IMappingExpression<TSource, TDestination> IgnoreUnmapped<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
{
var sourceType = typeof(TSource);
var destinationType = typeof(TDestination);
var key =$"{sourceType.FullName}__||__{destinationType.FullName}" ;
var t = list[key];
foreach (var item in destinationType.GetProperties())
{
if (!t.Contains(item.Name)) {
expression.ForMember(item.Name, x => x.Ignore());
}
}
return expression;
}
public static IMappingExpression<TSource, TDestination> ForAbdusselamMember<TSource, TDestination, TMember>(this IMappingExpression<TSource, TDestination> expression,
Expression<Func<TDestination, TMember>> destinationMember, Action<IMemberConfigurationExpression<TSource, TDestination, TMember>> memberOptions )
{
var sourceType = typeof(TSource);
var destinationType = typeof(TDestination);
var key = $"{sourceType.FullName}__||__{destinationType.FullName}";
if (!list.ContainsKey(key))
{
list[key]=new List<string>();
}
expression.ForMember(destinationMember, memberOptions);
var memberInfo = ReflectionHelper.FindProperty(destinationMember);
list[key].Add(memberInfo.Name);
return expression;
}
}
其他回答
我知道这是个老问题,但是@jmoerdyk 在你的问题中:
如何在配置文件中的链式creatatemap()表达式中使用它?
你可以像这样在Profile中使用这个答案
this.IgnoreUnmapped();
CreateMap<TSource, Tdestination>(MemberList.Destination)
.ForMember(dest => dest.SomeProp, opt => opt.MapFrom(src => src.OtherProp));
我已经更新了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被删除
这似乎是一个老问题,但我想我会把我的答案贴出来给那些长得像我的人。
我使用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());
对于那些使用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字段。
根据我的理解,这个问题是,目标上的字段在源中没有映射字段,这就是为什么您要寻找方法来忽略那些非映射的目标字段。
而不是实现和使用这些扩展方法,您可以简单地使用
Mapper.CreateMap<sourceModel, destinationModel>(MemberList.Source);
现在,automapper知道它只需要验证所有源字段都映射了,而不是相反。
你还可以使用:
Mapper.CreateMap<sourceModel, destinationModel>(MemberList.Destination);