【问题标题】:Merge two collections with Automapper by condition使用 Automapper 按条件合并两个集合
【发布时间】:2012-09-25 08:48:48
【问题描述】:

有两种类型:

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>

为简单起见,让我们考虑一下,这些集合中的 items count 是相等的,但 items 的顺序 可能不同。

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

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

这可能与 Automapper 相关吗?

【问题讨论】:

    标签: c# automapper


    【解决方案1】:

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

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

    【讨论】:

      【解决方案2】:

      另一种解决方案可以简单地将 linq 查询 + 自动映射器结合起来。

      这里展示了基本概念:

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

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

      【讨论】:

        【解决方案3】:

        我以遗传方式修改了 k0stya 的答案

         public class ListToListConverter<TEntity,TDto> : ITypeConverter<Collection<TDto>, Collection<TEntity>>
            where TEntity : class
            where TDto:BaseDto
        {
            public Collection<TEntity> Convert(Collection<TDto> dtos, Collection<TEntity> entities,ResolutionContext context)
            {
                var destCollection=new Collection<TEntity>();   
                foreach (var source in dtos)
                {
                    var dest = entities.SingleOrDefault(d => ((dynamic)d).Id == source.Id);
                    context.Mapper.Map(source, dest);
                    destCollection.Add(dest);  
                }
                return destCollection;
            }
        }
        

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-06-05
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多