我的对象结构是
Class cls1
{
id,
name,
List<Address> address
}
Class cls2
{
prop1,
prop2,
street,
HouseNumber
}
我想将cls1映射到cls2,其中cls2.street应该使用Address对象的street属性进行映射。
当我尝试Mapper.CreateMap<cls1, cls2>().ForMember(gn => gn.Street, item => item.MapFrom(i => i.address. ...)
时,它会显示为一个集合。
如何使用Automapper
答案 0 :(得分:0)
cls2的每个实例代表一个地址,以及一些其他信息。 cls1的每个实例都有一个地址集合。因此,除非您假设每个cls1实例中只有一个地址,否则无法直接从cls1映射到cls2。
为了克服这个问题,通过引入表示地址加上其父cls1的非规范化对象,将单个cls1映射到多个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);
}
另一方面,如果每个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");
}