如何在AutoMapper中全局忽略?

时间:2011-12-29 03:41:41

标签: c# mapping automapper

以下是它现在的样子。 DestinationA和DestinationB派生自某个DestinationBase类。我需要忽略所有这些派生类的一些常见属性。无论如何应用这些忽略选项全局而不必重复所有派生目标类?

Mapper.CreateMap<SourceA, DestinationA>()
      .ForMember(d => d.PropA, opt => opt.Ignore())
      .ForMember(d => d.PropB, opt => opt.Ignore())
      .ForMember(d => d.PropC, opt => opt.Ignore());

Mapper.CreateMap<SourceB, DestinationB>()
      .ForMember(d => d.PropA, opt => opt.Ignore())
      .ForMember(d => d.PropB, opt => opt.Ignore())
      .ForMember(d => d.PropC, opt => opt.Ignore());

我期待这样的事情:

Mapper.CreateMap<DestinationBase>().ForAllSource()
      .ForMember(d => d.PropA, opt => opt.Ignore())
      .ForMember(d => d.PropB, opt => opt.Ignore())
      .ForMember(d => d.PropC, opt => opt.Ignore());

5 个答案:

答案 0 :(得分:2)

现在有一个方法FindTypeMapFor,它使这个扩展方法更小(更有效率?):

public static IMappingExpression<TSource, TDestination> IgnoreAllNonMapped<TSource, TDestination>(this IMappingExpression<TSource, TDestination> expression)
    {
        foreach (var property in Mapper.FindTypeMapFor<TSource, TDestination>().GetUnmappedPropertyNames())
        {
            expression.ForMember(property, opt => opt.Ignore());
        }
        return expression;
    }

答案 1 :(得分:2)

我遇到了同样的问题,并在寻求帮助时遇到了这个老问题。我最终想出了以下解决方案。也许这对其他人有帮助......

我有几个派生自基类的类。我想从任何从基类派生的类的映射中排除该基类的属性。在创建我的映射(并且没有指定任何忽略选项)之后,我这样做:

foreach(var map in Mapper.GetAllTypeMaps())
{
    if (typeof(MyBaseClass).IsAssignableFrom(map.DestinationType))
    {
        var propInfo = map.DestinationType.GetProperty("PropertyToIgnore");
        if (propInfo != null) {
            map.FindOrCreatePropertyMapFor(new AutoMapper.Impl.PropertyAccessor(propInfo)).Ignore();
        }
    }
}

这是一种蛮力,因为我必须遍历所有类型的地图,但它完成了工作。

编辑:在if语句

中添加了遗漏{

答案 2 :(得分:0)

请参阅schdr在此处的IgnoreAllNonExisting()扩展名:
AutoMapper: "Ignore the rest"?

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>()
                .IgnoreAllNonExisting();

答案 3 :(得分:0)

您可以全局忽略所有未映射的属性。 虽然这与automapper的主要优点相矛盾,但只允许进行显式映射: 这适用于Automapper 6:

    var mapperConfiguration = new MapperConfiguration(cfg =>
    {
        cfg.AddProfile(new MyProfile());
        // ignore all unmapped properties globally
        cfg.ForAllMaps((map, exp) => exp.ForAllOtherMembers(opt => opt.Ignore()));
    });

答案 4 :(得分:0)

我不确定哪个版本添加了属性,但是这些天您可以这样做。 Docs

[Ignore]
public string Property { get; set; }

该方法的问题是您在域实体之间泄漏了AutoMapper的实现,这不是很好。

一种更好的方法似乎是通过定义自己的MapperConfiguration委托或对默认实现附加条件来在ShouldMapProperty上全局设置过滤。 Docs

var configuration = new MapperConfiguration(cfg =>
{
    cfg.ShouldMapField = ...;

    cfg.ShouldMapProperty = ...;
});

撰写本文时的默认实现为here。值得注意的是,ShouldMapProperty如果未指定为p => p.IsPublic(),则会回退。这样您就可以p => p.IsPublic() && p.DeclaringType != typeof(SomeBaseType) && p.Name == nameof(SomeBaseType.SomePropertyToIgnore)了。