简体   繁体   English

AutoMapper - Map collections 不同类型到另一种类型的嵌套集合

[英]AutoMapper - Map collections of different types to collection of another type with nesting

I am currently struggling with AutoMapper version 10.1.1 config.我目前正在努力使用 AutoMapper 版本 10.1.1 配置。 I have the following types:我有以下类型:

class Response
{
    List<Assignment> Assignments { get; }
    List<Product> Products { get; }
}

class Assignment
{
    int AssignmentId { get; set; }
    int ProductId { get; set; } // references Product.ProductId
}

class Product
{
    int ProductId { get; set; }
}

class AssignmentModel
{
    int AssignmentId { get; set; }
    int ProductId { get; set; }
    Product Product { get; set; }
}

For every item in the "Assignments" property of the response object, I would like to get a new AssignmentModel with the corresponding product based on the product id.对于响应 object 的“Assignments”属性中的每一项,我想根据产品 ID 获得一个具有相应产品的新 AssignmentModel。

The current solution works by mapping the Assignments into new AssignmentModels and the Products into the existing AssignmentModels.当前解决方案的工作原理是将 Assignments 映射到新的 AssignmentModels,并将 Products 映射到现有的 AssignmentModels。 The downside is, that I have to call the mapper twice.缺点是,我必须两次调用映射器。

cfg.CreateMap<Assignment, AssignmentModel>();
cfg.CreateMap<Product, AssignmentModel>()
    .ForMember(
        d => d.Product, opt => opt.MapFrom(s => s))
    .EqualityComparison((s, d) => s.ProductId == d.ProductId)
    .ForAllOtherMembers(opt => opt.Ignore());

var assignments = mapper.Map<ICollection<AssignmentModel>>(response.Assignments);
mapper.Map(response.Products, assignments); // not using the result because it does not return assignments without products
return assignments;

Is it possible to do that in one call?是否可以在一个电话中做到这一点? Like so:像这样:

return mapper.Map<ICollection<AssignmentModel>>(response);

Would suggest using Custom Type Resolver for your scenario.建议为您的场景使用自定义类型解析器

Mapping Configuration / Profile映射配置/配置文件

cfg.CreateMap<Assignment, AssignmentModel>();
            
cfg.CreateMap<Response, ICollection<AssignmentModel>>()
    .ConvertUsing<ResponseAssignmentModelCollectionConverter>();

In the Custom Type Converter:在自定义类型转换器中:

  1. source.Assignments Map to List<AssignmentModel> . source.Assignments Map 到List<AssignmentModel>
  2. Use LINQ .Join() to join the result from 1 and source.Products by ProductId .使用 LINQ .Join()通过ProductId加入1source.Products的结果。
public class ResponseAssignmentModelCollectionConverter : ITypeConverter<Response, ICollection<AssignmentModel>>
{
    public ICollection<AssignmentModel> Convert(Response source, ICollection<AssignmentModel> destination, ResolutionContext context)
    {
        var _mapper = context.Mapper;

        var result = _mapper.Map<List<AssignmentModel>>(source.Assignments);
        result = result.Join(source.Products, 
        a => a.ProductId, 
        b => b.ProductId, 
        (a, b) =>
        {
            a.Product = b;
            return a;
        })
        .ToList();

        return result;
    }
}
mapper.Map<ICollection<AssignmentModel>>(response);

Sample Demo on .NET Fiddle .NET Fiddle 上的示例演示

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM