【问题标题】:automapper - ignore mapping if property type is different with same property name - C#automapper - 如果属性类型与相同的属性名称不同,则忽略映射 - C#
【发布时间】:2016-06-28 14:00:30
【问题描述】:

如果属性类型与相同的属性名称不同,我如何忽略映射? 默认情况下它会抛出错误。

Mapper.CreateMap<EntityAttribute, LeadManagementService.LeadEntityAttribute>();

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

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

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

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

【问题讨论】:

  • 你试过了吗.ForAllMembers(opt => opt.Condition(IsValidType)));请参阅我的答案以获取示例源代码。

标签: c# .net automapper


【解决方案1】:

您可以使用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,试试map.Ignored = true。也许他们在写完答案后更改了 API。
  • 如果您使用 AutoMapper 8.0,请将 GetPropertyMaps() 替换为 PropertyMaps,将 DestinationPropertyType 替换为 DestinationType。
【解决方案2】:

你应该对应该被忽略的属性使用ignore:

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

【讨论】:

  • 我以后可能会添加新的属性。所以我需要忽略所有具有不同数据类型的属性的映射
  • 你不能。您所能做的就是在配置上编写自动测试,如果添加了问题字段,它将提醒您
【解决方案3】:

处理类型的所有属性的一种方法是使用 .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 类型的操作数 ..这个错误来了
  • 您可以发布更多详细信息或用您尝试过的内容更新您的问题吗?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2017-12-31
  • 2017-02-19
  • 2011-06-26
  • 2023-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多