简体   繁体   English

使用自动映射器进行嵌套映射以收集对象

[英]Nested mapping using automapper for collection of object

my objects structures are 我的对象结构是

Class cls1
{
    id,
    name,
    List<Address> address
}

Class cls2
{
    prop1,
    prop2,
    street,
    HouseNumber
}

I want to map cls1 to cls2 where cls2.street should map with street property of Address object. 我想将cls1映射到cls2,其中cls2.street应该使用Address对象的street属性进行映射。

when i'm trying to Mapper.CreateMap<cls1, cls2>().ForMember(gn => gn.Street, item => item.MapFrom(i => i.address. ...) it is show as a collection. how to resolve this mapping using Automapper 当我尝试Mapper.CreateMap<cls1, cls2>().ForMember(gn => gn.Street, item => item.MapFrom(i => i.address. ...)时显示为集合。如何使用Automapper解决此映射

Each instance of cls2 represents an address, plus some other information. cls2的每个实例代表一个地址,以及一些其他信息。 Each instance of cls1 has a collection of address. cls1的每个实例都有一个地址集合。 So it will not be possible to map directly from cls1 to cls2, unless you assume there is only one address in each instance of cls1. 因此,除非您假设在cls1的每个实例中只有一个地址,否则不可能直接从cls1映射到cls2。

To overcome this, map a single cls1 to multiple cls2 by introducing a denormalised object that represents an address plus its parent cls1. 为了克服这个问题,通过引入代表地址及其父cls1的非规范化对象,将单个cls1映射到多个cls2。 The mapping can then be from the denormalised representation to cls2. 然后,映射可以从非规范化表示形式到cls2。

public class Cls1AndAddress
{
    public Cls1 Cls1;
    public Address Address;
}

[Test]
public void DenormalizationApproach()
{
    AutoMapper.Mapper.CreateMap<Cls1AndAddress, Cls2>()
        .ForMember(dest => dest.Prop1, opt => opt.MapFrom(src => src.Cls1.Name))
        .ForMember(dest => dest.Street, opt => opt.MapFrom(src => src.Address.Street))
        .ForMember(dest => dest.HouseNumber, opt => opt.MapFrom(src => src.Address.HouseNumber))
        ;

    var c1 = new Cls1
    {
        Addresses = new List<Address>
        {
            new Address {Street = "foo", HouseNumber = 1},
            new Address {Street = "bar", HouseNumber = 2},
        }
    };

    var denormalized = c1.Addresses.Select(address => new Cls1AndAddress {Cls1 = c1, Address = address});

    var c2 = AutoMapper.Mapper.Map<IEnumerable<Cls1AndAddress>, IEnumerable<Cls2>>(denormalized);

    var c2Array = c2.ToArray();
    Assert.AreEqual(2, c2Array.Length);
    Assert.AreEqual("foo", c2Array[0].Street);
    Assert.AreEqual("bar", c2Array[1].Street);
}

On the other hand, if there is only one address per cls1, you could use the more direct route of assuming this in your mapping: 另一方面,如果每个cls1只有一个地址,则可以在映射中使用更直接的途径进行假设:

[Test]
public void AssumeSingleApproach()
{
    AutoMapper.Mapper.CreateMap<Cls1, Cls2>()
        .ForMember(dest => dest.Street, opt => opt.MapFrom(src => src.Addresses.Single().Street))
        .ForMember(dest => dest.HouseNumber, opt => opt.MapFrom(src => src.Addresses.Single().HouseNumber))
        ;

    var c1 = new Cls1
    {
        Addresses = new List<Address>
        {
            new Address {Street = "foo", HouseNumber = 1},
            // new Address {Street = "bar", HouseNumber = 2}, This would cause failure
        }
    };

    var c2 = AutoMapper.Mapper.Map<Cls1, Cls2>(c1);

    Assert.AreEqual(c2.Street, "foo");
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM