按条件合并两个集合与Automapper

时间:2012-09-25 08:48:48

标签: c# automapper

有两种类型:

1)DTO类型:

[DataContract]
public sealed class OrderDetailDto
{
    [DataMember]
    public Guid MergeId { get; set; }
    [DataMember]
    public int Id { get; set; }
    [DataMember]
    public string PostionName { get; set; }
    [DataMember]
    public decimal Quantity { get; set; }
    [DataMember]
    public byte[] Version { get; set; }
}

2)相应的域类型:

public sealed class OrderDetail
{
    public Guid MergeId { get; set; }
    public int Id { get; set; }
    public string PostionName { get; set; }
    public decimal Quantity { get; set; }
    public byte[] Version { get; set; }
}

和两个集合:Collection<OrderDetail>Collection<OrderDetailDto>

Collection<OrderDetailDto>有数据更改,这是在某处。现在,我想使用Automapper将这些更改应用于Collection<OrderDetail>

为简单起见,我们认为这些集合中的项目计数是相等的,但项目的顺序可能会有所不同。

要正确映射集合项,我想使用MergeId属性。我需要这样的东西:

Mapper.CreateMap<Collection<OrderDetailDto>, Collection<OrderDetail>>()
  .MappingExpression((dto, do) => dto.MergeId == do.MergeId);

这可以与Automapper一起使用吗?

2 个答案:

答案 0 :(得分:2)

我没有找到比使用下面的自定义转换器更好的解决方案。

    public class Converter : ITypeConverter<Collection<OrderDetailDto>, Collection<OrderDetail>>
    {
        public Collection<OrderDetail> Convert(ResolutionContext context)
        {
            var destCollection = (Collection<OrderDetail>) context.DestinationValue;
            var sourceCollection = (Collection<OrderDetailDto>)context.SourceValue;
            foreach (var source in sourceCollection)
            {
                var dest = destCollection.SingleOrDefault(d => d.MergeId == source.MergeId);
                Mapper.Map(source, dest);
            }
            return destCollection;
        }
    }

答案 1 :(得分:1)

另一个解决方案可以简单地组合linq查询+ automapper。

基本概念如下所示:

   var res = from a in orderDetails
              join b in orderDetailsDto on a.MergeId equals b.MergeId
              where a.Update == true // determine update selector here
              select new { a, b };

    res.Each(item => Mapper.Map<OrderDetail, OrderDetailDto>(item.a, item.b));

为所有合并提取通用扩展方法(基于连接扩展方法)也很容易