How to map from a flat entity to more than one DTO?

坚强是说给别人听的谎言 提交于 2019-12-04 20:10:25

You need to implement your own Converter like below:

  1. ProductsConverter

    public class ProductsConverter : ITypeConverter<List<Product>, List<ProductDto>>
    {
        public List<ProductDto> Convert(List<Product> source, List<ProductDto> destination, ResolutionContext context)
        {
            return source.GroupBy(p => p.Name)
                        .Select(r => new ProductDto
                        {
                            Name = r.Key,
                            Prices =  source.Where(pp => pp.Name == r.Key)
                                                        .Select(rr => new PriceDto
                                                        {
                                                            Price = rr.Price,
                                                            Weight = rr.Weight
                                                        })
                        }).ToList();
        }
    }
    
  2. ModelProfile

    public class ModelProfile: Profile
    {
        public ModelProfile()
        {
            CreateMap<List<Product>, List<ProductDto>>()
                .ConvertUsing<ProductsConverter>();
        }
    }
    
  3. Use Case

    public IActionResult Index()
    {
        List<Product> products= new List<Product>() {
            new Product{ Id = 1, Name = "foo", Price = 8, Weight = 12},
            new Product{ Id = 2, Name = "foo", Price = 12, Weight = 18},
            new Product{ Id = 3, Name = "bar", Price = 3, Weight = 1},
            new Product{ Id = 4, Name = "bar", Price = 6, Weight = 2},
        };
        var result = _mapper.Map<List<ProductDto>>(products);
        return Ok(result);
    }
    

I would define two domain profiles. One for Product to ProductDto

CreateMap<Product, ProductDto>()
  .ForMember(x => x.Id , opts => opts.Ignore())
  .ForMember(x => x.Price , opts => opts.Ignore())
  .ForMember(x => x.Weight , opts => opts.Ignore())
  .ForMember(x => x.Name , opts => opts.MapFrom(y => y.Name));

And one for Product to PriceDto

CreateMap<Product, ProductDto>()
  .ForMember(x => x.Id , opts => opts.Ignore())
  .ForMember(x => x.Name , opts => opts.Ignore())
  .ForMember(x => x.Price , opts => opts.MapFrom(y => y.Price ))
  .ForMember(x => x.Weight , opts => opts.MapFrom(y => y.Weight ));

And then do one mapping at a time from same source to two different targets.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!