2012-02-17 169 views
4

我有一个Customers EF POCO类,其中包含对地址表的引用。使用自动映射器映射嵌套对象

以下代码似乎可行,但我不确定它是否是最干净的方式。有没有更好的方法来映射这只使用一个Map调用?

[HttpGet] 
    public ActionResult Details(string ID) 
    { 
     BusinessLogic.Customers blCustomers = new BusinessLogic.Customers("CSU"); 
     DataModels.Customer customer = blCustomers.GetCustomer(ID); 

     CustomerDetailsViewModel model = new CustomerDetailsViewModel(); 

     Mapper.CreateMap<DataModels.Customer, CustomerDetailsViewModel>(); 
     Mapper.CreateMap<DataModels.Address, CustomerDetailsViewModel>(); 
     Mapper.Map(customer, model); 
     Mapper.Map(customer.Address, model); 

     return View(model); 
    } 

回答

14

这取决于您的CustomerDetailsViewModel的外观。例如,如果你的Address类看起来是这样的:

public class Address 
{ 
    public string Street { get; set; } 
    public string City { get; set; } 
} 

CustomerDetailsViewModel包含此约定以下属性:

当您配置在AutoMapper源/目标类型对, 配置尝试将源 类型的属性和方法匹配到目标类型的属性。如果对于目标类型为 的任何属性,在源类型上不存在以“获取” 为前缀的属性,方法或方法,AutoMapper会将目标成员名称分割为单独的单词(按PascalCase约定)。

(来源:Flattening

然后,如果CustomerDetailsViewModel有属性:

public string AddressStreet { get; set; } 
public string AddressCity { get; set; } 

刚刚从CustomerCustomerDetailsViewModel一个映射将正常工作。对于不符合该惯例的会员,您可以使用ForMember

您可以随时使用ForMember为每一个地址属性,以及:

Mapper.CreateMap<DataModels.Customer, CustomerDetailsViewModel>() 
    .ForMember(dest => dest.Street, opt => opt.MapFrom(src => src.Address.Street)); 
    /* etc, for other address properties */ 

就个人而言,我不会太担心调用.Map两次。至少这种方式非常清楚,AddressCustomer属性正在映射。