有没有一种方法告诉AutoMapper忽略所有的属性,除了那些显式映射的?

我有可能从外部更改的外部DTO类,并且我希望避免显式地指定要忽略的每个属性,因为添加新属性将在尝试将它们映射到自己的对象时破坏功能(导致异常)。


当前回答

对于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字段的输出对象将被解析,所有其他将被跳过。工作就像一个魅力,似乎我们不需要任何棘手的扩展了!

其他回答

您希望如何指定忽略某些成员?是否有您想要应用的约定、基类或属性?一旦您开始显式地指定所有映射,我不确定您能从AutoMapper中得到什么价值。

对于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字段的输出对象将被解析,所有其他将被跳过。工作就像一个魅力,似乎我们不需要任何棘手的扩展了!

我更新了Robert Schroeder对AutoMapper 4.2的答案。对于非静态映射器配置,我们不能使用mapper . getalltypemaps(),但表达式有一个对所需的TypeMap的引用:

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

版本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;
        }
          
    }

默认情况下,AutoMapper使用目标类型来验证成员,但您可以通过使用MemberList跳过验证。没有选择。

var configuration = new MapperConfiguration(cfg =>
  cfg.CreateMap<Source2, Destination2>(MemberList.None);
);

你可以在这里找到参考资料