自动映射器合并对象问题 [英] Automapper merging objects issue

查看:62
本文介绍了自动映射器合并对象问题的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使自动映射器正常工作(上一个问题)之后,我在努力另一个问题(解决另一个问题,所以第一个问题不会太复杂)...

After getting automapper to work (previous question), I'm struggling with another problem (took it to another question, so the first one wouldn't be too complicated)...

我有下一节课:

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配置类(从Global.asax调用):

And AutoMapper configuration class (called from 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并填充了数据):

When I need the object to be converted, I do next (at this point I have _superModel initialized and filled with data):

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

因此,我将Model1映射到Entity1(巫婆很好),也将Model2映射到Entity2(巫婆也很好,除了Id属性,它被忽略了).

So, I map Model1 to Entity1 (witch is fine), and also Model2 to Entity2 (witch is also fine, except the Id property, which is ignored).

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

Main objects SuperModel and SuperEntity are mapped as well, and seems to work fine.

当我将Model1映射到Entity2以获得NickName时,会发生问题(认为其余属性会被忽略). null总是如此!

The problem happens, when I map Model1 to Entity2, to get the NickName (thought the rest of the properties are ignored). Some how It is always null!

有什么想法吗?

推荐答案

问题是您要从多个源属性值(ChildrenMarriedHasPet)映射目标属性(Entity2) Model2Nickname来自Model1).

The problem is you want to map a destination property (Entity2) from multiples source property values (Children, Married and HasPet from Model2 and Nickname from Model1).

您可以使用自定义解析器或使用<一个href ="https://github.com/AutoMapper/AutoMapper/wiki/Before-and-after-map-actions" rel ="nofollow"> AfterMap 方法.

You can solve your situation using an Custom Resolver or with AfterMap method.

使用自定义解析器:

您必须创建一个继承自ValueResolver的类,以定义如何从SuperModel映射Entity2:

You have to create a class inhering from ValueResolver to define how you will map Entity2 from an SuperModel:

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:

You can execute actions after the mapping, so pass the value from Model1.Nickname to Entity2.Nickname after the map:

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);

这篇关于自动映射器合并对象问题的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆