如何从一个平面实体映射到多个DTO? [英] How to map from a flat entity to more than one DTO?

查看:304
本文介绍了如何从一个平面实体映射到多个DTO?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我希望在C#.NET Core中使用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; }
}

我知道AutoMapper提供的ReverseMap()函数,但是鉴于我是从一个扁平化的实体开始开始,所以我不确定如何建立ProductDto和PriceDto之间的关系./p>

这是我以产品"形式接收的一组扁平化数据的示例.请注意,将需要推断出ProductDto和PriceDto之间的一对多关系.

+-----+-------+-------+--------+
| Id  | Name  | Price | Weight |
+-----+-------+-------+--------+
|   1 | "foo" |     8 |     12 |
|   2 | "foo" |    12 |     18 |
|   3 | "bar" |     3 |      1 |
|   4 | "bar" |     6 |      2 |
| ... |       |       |        |
+-----+-------+-------+--------+

解决方案

您需要实现自己的Converter,如下所示:

  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. 用例

    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'm wishing to use AutoMapper in C# .NET Core to map from an already flattened entity to a nested set of DTO's. Also the DTO’s have a one to many relationship, which the flattened entity is hiding in structure. For example:

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

I'm aware of the ReverseMap() function provided by AutoMapper, however given that I am starting with a flattened entity I'm not sure how set up the relationship between ProductDto and PriceDto.

EDIT: Here's an example set of the flattened data that I receive in the form of "Product". Notice the inferred one-to-many relationship between the ProductDto and PriceDto which will be needed.

+-----+-------+-------+--------+
| Id  | Name  | Price | Weight |
+-----+-------+-------+--------+
|   1 | "foo" |     8 |     12 |
|   2 | "foo" |    12 |     18 |
|   3 | "bar" |     3 |      1 |
|   4 | "bar" |     6 |      2 |
| ... |       |       |        |
+-----+-------+-------+--------+

解决方案

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

这篇关于如何从一个平面实体映射到多个DTO?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆