扁平化映射
对象-对象映射的一个常见用法是采用复杂的对象模型并将其扁平化为更简单的模型。 你可以采取一个复杂的模型,如:
public class Order
{
private readonly IList<OrderLineItem> _orderLineItems = new List<OrderLineItem>();
public Customer Customer { get; set; }
public OrderLineItem[] GetOrderLineItems()
{
return _orderLineItems.ToArray();
}
public void AddOrderLineItem(Product product, int quantity)
{
_orderLineItems.Add(new OrderLineItem(product, quantity));
}
public decimal GetTotal()
{
return _orderLineItems.Sum(li => li.GetTotal());
}
}
public class Product
{
public decimal Price { get; set; }
public string Name { get; set; }
}
public class OrderLineItem
{
public OrderLineItem(Product product, int quantity)
{
Product = product;
Quantity = quantity;
}
public Product Product { get; private set; }
public int Quantity { get; private set;}
public decimal GetTotal()
{
return Quantity*Product.Price;
}
}
public class Customer
{
public string Name { get; set; }
}
我们希望将这个复杂的Order
对象变成一个更简单的OrderDto
,其中只包含特定场景所需的数据:
public class OrderDto
{
public string CustomerName { get; set; }
public decimal Total { get; set; }
}
在AutoMapper
中配置源/目标类型对时,配置程序会尝试将源类型的属性和方法匹配到目标类型的属性。 如果对于目标类型的任何属性,源类型中不存在以Get
为前缀的属性,方法或方法,则AutoMapper
会将目标成员名称拆分为单个单词(按PascalCase约定)。
//复杂的模型
var customer = new Customer
{
Name = "George Costanza"
};
var order = new Order
{
Customer = customer
};
var bosco = new Product
{
Name = "Bosco",
Price = 4.99m
};
order.AddOrderLineItem(bosco, 15);
//配置AutoMapper
Mapper.Initialize(cfg => cfg.CreateMap<Order, OrderDto>());
//执行映射
OrderDto dto = Mapper.Map<Order, OrderDto>(order);
dto.CustomerName.ShouldEqual("George Costanza");
dto.Total.ShouldEqual(74.85m);
我们使用CreateMap
方法在AutoMapper
中配置了类型映射。 AutoMapper
只能映射它所知道的类型对,所以我们已经用CreateMap
显式地注册了源/目标类型对。 为了执行映射,我们使用Map
方法。
在OrderDto类型上,Total
属性与Order
上的GetTotal()
方法匹配。 CustomerName
属性与Order
上的Customer.Name
属性匹配。 只要我们适当地命名我们的目的地属性,我们不需要配置个别的属性匹配。