AutoMapper - 如果属性类型不同且属性名称相同,则忽略映射 - C#

8
如何忽略映射,如果属性类型与相同的属性名称不同? 默认情况下会抛出错误。
Mapper.CreateMap<EntityAttribute, LeadManagementService.LeadEntityAttribute>();

Model = Mapper.Map<EntityAttribute, LeadManagementService.LeadEntityAttribute>(EntityAttribute);

我知道一种指定要忽略的属性名的方法,但这不是我想要的。

  .ForMember(d=>d.Field, m=>m.Ignore());

因为将来可能会添加新的属性,所以我需要忽略所有具有不同数据类型的属性的映射。


你尝试过 .ForAllMembers(opt => opt.Condition(IsValidType))); 吗?请参考我的答案中的示例源代码。 - Vinod
3个回答

5

您应该使用 ignore 来忽略需要被忽略的属性:

Mapper.CreateMap<EntityAttribute, LeadManagementService.LeadEntityAttribute>()
     ForMember(d=>d.FieldToIgnore, m=>m.Ignore());

1
我可能会在未来添加新的属性,因此我需要忽略所有数据类型不同的属性的映射。 - GorvGoyl
你无法做到。你所能做的就是在配置上编写自动测试,以便在添加问题字段时提醒你。 - Kirill Bestemyanov

5
你可以使用ForAllMembers()来设置适当的映射条件:
Mapper.Initialize(cfg =>
{
    cfg.CreateMap<EntityAttribute, LeadEntityAttribute>().ForAllMembers(memberConf =>
    {
        memberConf.Condition((ResolutionContext cond) => cond.DestinationType == cond.SourceType);
    });
}

您还可以使用 ForAllMaps() 全局应用它:

Mapper.Initialize(cfg =>
{
    // register your maps here
    cfg.CreateMap<A, B>();

    cfg.ForAllMaps((typeMap, mappingExpr) =>
    {
        var ignoredPropMaps = typeMap.GetPropertyMaps();

        foreach (var map in ignoredPropMaps)
        {
            var sourcePropInfo = map.SourceMember as PropertyInfo;
            if (sourcePropInfo == null) continue;

            if (sourcePropInfo.PropertyType != map.DestinationPropertyType)
                map.Ignore();
        }
    });
});

我尝试了第二个选项ForAllMaps(),但在map.Ignore()的最后一行中出现了错误。找不到Ignore方法。报错如下:CS1061 'PropertyMap' does not contain a definition for 'Ignore' and no extension method 'Ignore' accepting a first argument of type 'PropertyMap' could be found (are you missing a using directive or an assembly reference?) 你有什么想法吗? - Shiva
1
@Shiva,尝试使用map.Ignored = true。也许自回答以来API已经更改了。 - haim770
如果您使用AutoMapper 8.0,请将GetPropertyMaps()替换为PropertyMaps,并将DestinationPropertyType替换为DestinationType。 - PocoM

0

处理类型的所有属性的一种方法是使用 .ForAllMembers(opt => opt.Condition(IsValidType)))。我已经使用了AutoMapper的新语法,但即使使用旧语法也应该可以工作。

using System;
using AutoMapper;

namespace TestAutoMapper
{
    class Program
    {
        static void Main(string[] args)
        {
            var mapperConfiguration = new MapperConfiguration(cfg => cfg.CreateMap<Car, CarDto>()
                .ForAllMembers(opt => opt.Condition(IsValidType))); //and how to conditionally ignore properties
            var car = new Car
            {
                VehicleType = new AutoType
                {
                    Code = "001DXT",
                    Name = "001 DTX"
                },
                EngineName = "RoadWarrior"
            };

            IMapper mapper = mapperConfiguration.CreateMapper();
            var carDto = mapper.Map<Car, CarDto>(car);
            Console.WriteLine(carDto.EngineName);

            Console.ReadKey();
        }

        private static bool IsValidType(ResolutionContext arg)
        {
            var isSameType = arg.SourceType== arg.DestinationType; //is source and destination type is same?
            return isSameType;
        }
    }

    public class Car
    {
        public AutoType VehicleType { get; set; } //same property name with different type
        public string EngineName { get; set; }
    }

    public class CarDto
    {
        public string VehicleType { get; set; } //same property name with different type
        public string EngineName { get; set; }
    }

    public class AutoType
    {
        public string Name { get; set; }
        public string Code { get; set; }
    }
}

"ForAllMembers" 无法应用于 void 类型的操作数.. 出现了这个错误。 - GorvGoyl
你能否发布更多细节或更新你的问题,说明你已经尝试过什么? - Vinod

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接