Automapper 合并对象问题

Automapper merging objects issue

在让automapper工作后(),我正在努力解决另一个问题(把它带到另一个问题,所以第一个不会太复杂)...

我有下一个 classes:

public class Model1
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDay { get; set; }
    public int Gender { get; set; }
    public string NickName { get; set; }
}    
public class Model2
{
    public bool Married { get; set; }    
    public int Children { get; set; }
    public bool HasPet { get; set; }
}

public class Entity1
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
    public DateTime BirthDay { get; set; }
    public int Gender { get; set; }
}    
public class Entity2
{
    public bool Married { get; set; }    
    public int Children { get; set; }
    public bool HasPet { get; set; }
    public string NickName { get; set; }
}

除了名称和复杂性之外,这些对象与我的原始对象在原理上相似。

和 AutoMapper 配置 class(从 Global.asax 调用):

public class AutoMapperConfig
{
    public static MapperConfiguration MapperConfiguration { get; set; }

    public static void Configure()
    {
        MapperConfiguration = new MapperConfiguration(cfg => {
            cfg.AddProfile<Out>();
            cfg.CreateMap<SuperModel, SuperEntity>();
        });
        MapperConfiguration.AssertConfigurationIsValid();
    }
}

public class Out: Profile
{
   protected override void Configure()
    {
        CreateMap<Model1, Entity1>();
        CreateMap<Model2, Entity2>()
            .ForMember(dest => dest.NickName, opt => opt.Ignore());
        CreateMap<Model1, Entity2>()
            .ForMember(dest => dest.Married, opt => opt.Ignore())
            .ForMember(dest => dest.Children, opt => opt.Ignore())
            .ForMember(dest => dest.HasPet, opt => opt.Ignore());
        CreateMap<SuperModel, SuperEntity>()
            .ForMember(dest => dest.Entity1, opt => opt.MapFrom(src => src.Model1))
            .ForMember(dest => dest.Entity2, opt => opt.MapFrom(src => src.Model2));
    }
}

当我需要转换对象时,我会做下一步(此时我已经 _superModel 初始化并填充了数据):

SuperEntity _superEntity = new SuperEntity();
AutoMapperConfig.MapperConfiguration.CreateMapper().Map<SuperModel, SuperEntity>(_superModel, _superEntity);

所以,我将 Model1 映射到 Entity1( 可以),并将 Model2 映射到 Entity2(也很好,除了 Id 属性,它被忽略了)。

主要对象 SuperModelSuperEntity 也已映射,并且似乎工作正常。

当我将 Model1 映射到 Entity2 以获取 NickName 时,问题发生了(认为其余属性被忽略)。有些怎么总是null!

有什么想法吗?

问题是您想从多个源 属性 值(ChildrenMarriedHasPet 来自 Model2Nickname 来自 Model1).

您可以使用 Custom Resolver or with AfterMap 方法解决您的问题。

使用自定义解析器:

您必须创建一个继承自 ValueResolver 的 class 来定义如何从 SuperModel:

映射 Entity2
public class CustomResolver : ValueResolver<SuperModel, Entity2>
{
    protected override Entity2 ResolveCore(SuperModel source)
    {
        return new Entity2
        {
            Children = source.Model2.Children,
            HasPet = source.Model2.HasPet,
            Married = source.Model2.Married,
            NickName = source.Model1.NickName
        };
    }
}

然后,像这样使用它:

CreateMap<SuperModel, SuperEntity>()
    .ForMember(dest => dest.Entity1, opt => opt.MapFrom(src => src.Model1))
    .ForMember(dest => dest.Entity2, opt => opt.ResolveUsing<CustomResolver>());

使用 AfterMap:

您可以在映射后执行操作,因此在映射后将值从 Model1.Nickname 传递到 Entity2.Nickname

CreateMap<SuperModel, SuperEntity>()
    .ForMember(dest => dest.Entity1, opt => opt.MapFrom(src => src.Model1))
    .ForMember(dest => dest.Entity2, opt => opt.MapFrom(src => src.Model2))
            .AfterMap((m, e) => e.Entity2.NickName = m.Model1.NickName);