如何忽略所有目标成员,除了映射的成员?

时间:2010-12-06 14:50:45

标签: c# automapper

有办法做到这一点吗?我们有一个SummaryDto,它映射了三种不同的类型,当我们为每种类型创建一个map时,未映射的props会抛出错误。摘要dto上有大约35个属性。要在每个上使用Ignore()选项太麻烦了。全球忽视了吗?像

这样的东西
CreateMap<Source,Target>()
   .IgnoreAllUnmapped();

5 个答案:

答案 0 :(得分:110)

这对我有用:

public static class MappingExpressionExtensions
{
    public static IMappingExpression<TSource, TDest> IgnoreAllUnmapped<TSource, TDest>(this IMappingExpression<TSource, TDest> expression)
    {
        expression.ForAllMembers(opt => opt.Ignore());
        return expression;
    }
}

由于ForAllMembers返回void,因此在没有此扩展方法的情况下调用ForAllMembers(o => o.Ignore())将无效。我们希望保持映射表达式可用于启用后续映射:

CreateMap<Source, Destination>()
            .IgnoreAllUnmapped()
            .ForMember(d => d.Text, o => o.MapFrom(s => s.Name))
            .ForMember(d => d.Value, o => o.MapFrom(s => s.Id));

答案 1 :(得分:29)

我也在这个问题上挣扎了很长一段时间,或者至少是与此类似的问题。我有一个有很多属性的类(大约30个),我只想映射其中的4个。添加26个忽略语句似乎很疯狂(特别是当它意味着未来对类的更改意味着必须更新它们时!)

我终于发现我可以告诉AutoMapper忽略所有内容,然后明确添加我想要的内容。

// Create a map, store a reference to it in a local variable
var map = CreateMap<Source,Target>();

// Ignore all members
map.ForAllMembers(opt => opt.Ignore());

// Add mapping for P1
map.ForMember(dest => dest.P1, opt => opt.MapFrom( src => src.P1));

// Add other mappings...
map.ForMember(dest => dest.P2, opt => opt.MapFrom( src => src.P2));
map.ForMember(dest => dest.P3, opt => opt.MapFrom( src => src.P3));
map.ForMember(dest => dest.P4, opt => opt.MapFrom( src => src.P4));

你认为你可以这样做(但不要因为它不会编译)你会被原谅:

// This won't compile
CreateMap<Source,Target>()
   .ForAllMembers(opt => opt.Ignore())
   .ForMember(dest => dest.P1, opt => opt.MapFrom( src => src.P1));

这不起作用的原因是ForAllMembers()方法不支持流畅的链接样式(至少在当前版本2.0中)。

好消息是非链接版本确实有效。当然需要注意的是,您需要明确告诉AutoMapper要映射哪些成员。我还没有找到一种简单的方法来使它既可以使用隐含的映射而忽略破坏的映射。

答案 2 :(得分:5)

为避免必须显式指定映射属性,您可以使用IgnoreAllNonExisting。它会忽略任何没有映射源属性的目标属性。

答案 3 :(得分:1)

尝试在您的情况下使用.ConvertUsing(),例如

CreateMap<Source,Target>()
 .ConvertUsing(converter=> new Target(){
P1 = converter.P1,
....
});

因此,您可以在对象中描述所有属性,其他属性将被忽略。

答案 4 :(得分:1)

扩展方法,允许ForAllMembers方法的流利语法:

public static IMappingExpression<TSource, TDestination> IgnoreAllMembers<TSource, TDestination>(
    this IMappingExpression<TSource, TDestination> expression
    )
{
    expression.ForAllMembers(opt => opt.Ignore());
    return expression;
}

用法:

对IgnoreAllMembers的调用必须在调用ForMember之前。

        CreateMap<LocationRevision, Dto.LocationAddressMap>()
            .IgnoreAllMembers()
            .ForMember(m => m.LocationId, opt => opt.MapFrom(src => src.Id))
            ;
相关问题