02.AutoMapper 之扁平化(Flattening)

weixin_34290000發表於2018-12-31

扁平化(Flattening)

物件對映器的常見用法是將一個複雜物件模型扁平化為一個簡單模型。例如您有一個以下複雜模型:

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);

AutoMapper中使用CreateMap方法配置型別對映。AutoMapper只能對映它識別的型別對,所以我們用CreateMap顯式註冊了源/目標型別對。使用Map方法執行對映。

OrderDto型別上,Total屬性與 Order型別的GetTotal() 方法匹配。CustomerName屬性與Order型別的Customer.Name匹配。只要目標屬性命名符合規定,就不需要在單獨配置屬性匹配規則。

相關文章