public class Customer { public Company Company { get; set; } } public class Company { public string Name { get; set; } } public class CustomerDTO { public string CompanyName { get; set; } }
static void Main(string[] args) { var customer = new Customer() { Company = new Company() { Name = } }; Mapper.Initialize(cfg => { cfg.CreateMap<Customer, CustomerDTO>(); }); var customerDTO = Mapper.Map<Customer, CustomerDTO>(customer); Console.ReadKey(); }
你看我们什么都没做,结果同样还是映射到了目标类中,不过是遵守了AutoMapper的映射约定罢了,看到这个想必大家就马上明白过来了。如果扁平化映射源类,若想AutoMapper依然能够自动映射,那么映射目标类中的属性必须是映射源中复杂属性名称加上复杂属性中的属性名称才行,因为AutoMapper会深度搜索目标类,直到找到匹配的属性为止。下面我们再来看看集合映射。
public class Customer { public int Id { get; set; } public string Name { get; set; } public IEnumerable<Order> Orders { get; set; } } public class Order { public int Id { get; set; } public string TradeNo { get; set; } public int TotalFee { get; set; } } public class CustomerDTO { public int Id { get; set; } public string Name { get; set; } public IEnumerable<OrderDTO> OrderDTOs { get; set; } } public class OrderDTO { public int Id { get; set; } public string TradeNo { get; set; } public int TotalFee { get; set; } }
上述Customer对象中有Order的集合属性,所以怕AutoMapper是映射不了,我们手动配置一下,如下:
static void Main(string[] args) { var customer = new Customer() { Id = 1, Name = , Orders = new List<Order>() { new Order() { Id =1, TotalFee = 10, TradeNo = } } }; Mapper.Initialize(cfg => cfg.CreateMap<Customer, CustomerDTO>() .ForMember(d => d.OrderDTOs, o => o.MapFrom(s => s.Orders)) ); var customerDTO = Mapper.Map<Customer, CustomerDTO>(customer); Console.ReadKey(); }
喔,抛出异常了,哈哈,果然AutoMapper还有不支持的,果断弃之(我们项目当时就是一直出这样的问题于是乎弃用了)。慢着,老铁。利用AutoMapper映射大部分情况下都会遇到如上异常,所以我们来分析下,在AutoMapper中,当它偶遇一个接口的目标对象时,它会自动生成动态代理类,怎么感觉好像说到EntityFramework了。 当映射到不存在的映射目标时,这就是内部设计的行为了。 然而然而,我们映射目标类却存在啊,于是乎我修改了AutoMapper映射,将Order到OrderDTO也进行映射配置,然后在配置映射Customer对象再指定Order集合属性,我们试试。
Mapper.Initialize(cfg => { cfg.CreateMap<Order, OrderDTO>(); cfg.CreateMap<Customer, CustomerDTO>() .ForMember(d => d.OrderDTOs, o => o.MapFrom(s => Mapper.Map<IList<Order>, IList<OrderDTO>>(s.Orders))); }); var customerDTO = Mapper.Map<Customer, CustomerDTO>(customer);