通过AutoMapper将IList映射到ICollection

时间:2011-03-30 07:21:22

标签: automapper

public class Order
{
    public int OrderId { get; set; }
    public string OrderCode { get; set; }
    public IList<OrderItem> OrderItems { get; set; }
}

public class OrderDTO
{
    public string OrderId { get; set; }
    public string IdentifiableCode { get; set; }
    public decimal TotalCost { get; set; }
    public ICollection OrderItems { get; set; }
}

public class OrderItem
{
    public int OrderItemId { get; set; }
    public int ItemCount { get; set; }
    public Order Order { get; set; }
}

public class OrderItemDTO
{
    public int OrderItemId { get; set; }
    public int ItemCount { get; set; }
    public OrderDTO Order { get; set; }
}

在这种情况下,我如何将OrderItems的IList映射到ICollection。我尝试使用解析器但最终以递归方式结束,因为OrderItem具有Order引用。

有什么想法吗?

1 个答案:

答案 0 :(得分:4)

首先,我为你的课程添加了一些调整。一个是添加初始化集合的构造函数,以便我可以在测试中添加它们。其次,我不明白为什么你想要OrderDTO.OrderItems是一个松散类型的ICollection。如果这样做,Automapper只会将IList分配给ICollection(因为IList实现了ICollection)。如果您将其定义为IList,Automapper将看到它知道如何从OrderItem转换为OrderItemDTO并将映射集合的每个成员。

我还必须添加一些Ignore(),因为OrderItemDTO不包含IdentifiableCode,也不包含TotalCost(不确定你想用它们做什么)。最后,父/子映射(OrderItemDTO具有对其父级的引用)可以通过AfterMap()中的简单foreach循环来完成。所以这是我提出的映射:

Mapper.CreateMap<Order, OrderDTO>()
    .ForMember(d => d.IdentifiableCode, o => o.Ignore())
    .ForMember(d => d.TotalCost, o => o.Ignore())
    .AfterMap((s, d) =>
                {
                    foreach (var l in d.OrderItems)
                    {
                        l.Order = d;
                    }
                });
Mapper.CreateMap<OrderItem, OrderItemDTO>();
Mapper.AssertConfigurationIsValid();

以下是我用来检验的测试:

var order = new Order
                {
                    OrderCode = "AAA",
                    OrderId = 22,
                    OrderItems = new List<OrderItem>(),
                };
order.OrderItems.Add(new OrderItem { ItemCount = 2, Order = order, OrderItemId = 33 });
order.OrderItems.Add(new OrderItem { ItemCount = 1, Order = order, OrderItemId = 99 });

var mapped = Mapper.Map<Order, OrderDTO>(order);