我有一个简单的 poco,需要映射到使用复杂对象层次结构的第三方提供的对象。如果可能的话,我想使用 AutoMapper,但我不确定如何正确设置它。
我在下面提供了一个简化的示例来展示我正在尝试做的事情。
我的poco:
public class Person
{
public string FirstName { get; set; }
public string Lastname { get; set; }
public string FullName { get { return Firstname + " " + Lastname; } }
public string AddressLine1 { get; set; }
public string AddressLine2 { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string Postcode { get; set; }
public string Reference { get; set; }
}
第三方对象
public class People
{
public Person[] Person { get; set; }
}
public class Person
{
public Names Names { get; set; }
public Address Address { get; set; }
public ReasonsForRequest[] Reasons { get; set; }
}
public class Names
{
public string Fullname { get; set; }
}
public class Address
{
public string AddressLine[] { get; set; }
public string City { get; set; }
public string Country { get; set; }
public string Postcode { get; set; }
}
public class ReasonsForRequest
{
public StructuredReasons StructuredReasons { get; set; }
}
public class StructuredReasons
{
public Reference Ref { get; set; }
}
public class Reference
{
public string Ref { get; set; }
}
我遇到的问题是注册映射以获取映射的引用。当我需要映射到内部对象和父对象时,如何将 mappig 注册到仅包含对象的对象?
最佳答案
[为了清楚起见,我将把您的 Person POCO 称为 PersonDTO
,因为第 3 方代码也有一个名为 Person
的类。]
有几种方法可以做到这一点。我过去使用过的一种方法是设置从 PersonDTO
到 Names
的映射,另一种是从 PersonDTO
到 Address 的映射
,另一个从 PersonDTO
到 Reasons
。最后,添加从 PersonDTO
到 Person
的映射。它看起来像这样(我省略了原因
,但你明白了):
var config = new MapperConfiguration(cfg =>
{
cfg.CreateMap<PersonDTO, Names>()
.ForMember(d => d.Fullname, o => o.MapFrom(s => s.FullName));
cfg.CreateMap<PersonDTO, Address>()
.ForMember(d => d.AddressLine,
o => o.MapFrom(s => new[] { s.AddressLine1, s.AddressLine2 }));
cfg.CreateMap<PersonDTO, Person>()
.ForMember(d => d.Names, o => o.MapFrom(s => s))
.ForMember(d => d.Address, o => o.MapFrom(s => s));
});
var mapper = config.CreateMapper();
var myPerson = new PersonDTO() {
FirstName = "Bob",
LastName = "Gold",
AddressLine1 = "123 Main Street",
AddressLine2 = "Apt. 2"
};
var theirPerson = mapper.Map<Person>(myPerson);
但是 AutoMapper 的最新版本添加了一个 ForPath()
方法,该方法允许您访问内部对象,从而使所有这些变得更简单。现在代码折叠为:
var config = new MapperConfiguration(cfg =>
cfg.CreateMap<PersonDTO, Person>()
.ForPath(d => d.Names.Fullname, o => o.MapFrom(s => s.FullName))
.ForPath(d => d.Address.AddressLine,
o => o.MapFrom(s => new[] { s.AddressLine1, s.AddressLine2 }))
);
var mapper = config.CreateMapper();
编辑:我遗漏了一个可能会改变这两种方法之间平衡的方面。在第一种方法中,定义了多个映射,您可以免费获得具有匹配名称的任何字段。例如,您不需要显式地将 PesronDTO.City
映射到 Address.City
(并且如果您更改 PersonDTO.FullName
上的大小写)成为 PersonDTO.Fullname
,您也可以免费获得)。但在第二种方法中,即使名称匹配,您也必须显式映射所有嵌套字段。就您而言,我认为第一种方法可能更适合您,因为您只需显式映射 3 个字段,并且可以免费获得其他 4 个字段。对于第二种方法,您必须对所有 7 个字段执行 ForPath()
。
关于c# - 如何使用自动映射器将简单的 poco 映射到复杂的对象层次结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/49152317/