C# 如何从平面图元映射到多个DTO?

C# 如何从平面图元映射到多个DTO?,c#,asp.net-core,automapper,C#,Asp.net Core,Automapper,我希望使用C#.NET核心中的AutoMapper将已经扁平化的实体映射到嵌套的DTO集合。此外,DTO具有一对多关系,扁平实体隐藏在结构中。例如: public class Product { public int Id { get; set; } public string Name { get; set; } public int Price { get; set; } public int Weight { get; set; } } public cl

我希望使用C#.NET核心中的AutoMapper将已经扁平化的实体映射到嵌套的DTO集合。此外,DTO具有一对多关系,扁平实体隐藏在结构中。例如:

public class Product
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int Price { get; set; }
    public int Weight { get; set; }
}

public class ProductDto
{
    public string Name { get; set; }
    public IEnumerable<PriceDto> Prices { get; set; }
}

public class PriceDto
{
    public int Price { get; set; }
    public int Weight { get; set; }
}

我将定义两个域配置文件。 一个用于产品到产品的转换

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));
CreateMap()
.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));
还有一个是产品定价

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 ));
CreateMap()
.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));

然后一次从同一个源映射到两个不同的目标。

您需要实现自己的转换器,如下所示:

  • 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();
        }
    }
    
    public class ModelProfile: Profile
    {
        public ModelProfile()
        {
            CreateMap<List<Product>, List<ProductDto>>()
                .ConvertUsing<ProductsConverter>();
        }
    }
    
  • 用例

    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);
    }
    
    public IActionResult Index()
    {
    列表产品=新列表(){
    新产品{Id=1,Name=“foo”,价格=8,重量=12},
    新产品{Id=2,Name=“foo”,价格=12,重量=18},
    新产品{Id=3,Name=“bar”,价格=3,重量=1},
    新产品{Id=4,Name=“bar”,价格=6,重量=2},
    };
    var result=_mapper.Map(产品);
    返回Ok(结果);
    }
    

  • 你的真实数据是什么?产品会有很多价格吗?与我们分享使用AutoMapper转换实体的代码。你好@TaoZhou是的,ProductDto将有许多PriceDto。我还没有关于CreateMap()设置的任何代码,因为这就是我目前正在研究的。我将用一组扁平化实体的示例更新帖子如果ProductDto和PriceDto之间分别存在一对多关系,该方法是否有效?如果将product映射到ProductDto,然后初始化ProductDto。Prices使用一个包含单个元素的列表将product映射到PriceDto,则该方法应该有效。它不会是全自动的,但据我所知它会工作的
    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);
    }