Как отобразить из плоской сущности на несколько DTO? - PullRequest
1 голос
/ 08 июля 2019

Я хочу использовать AutoMapper в C # .NET Core для отображения из уже сплющенной сущности во вложенный набор 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; }
}

Мне известно о функции ReverseMap (), предоставляемой AutoMapper, однако, учитывая, что я начинаю со сплющенной сущности, я не уверен, как установить отношения между ProductDto и PriceDto.

EDIT: Вот пример набора сглаженных данных, которые я получаю в форме «Продукт». Обратите внимание на предполагаемые отношения один-ко-многим между ProductDto и PriceDto, которые понадобятся.

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

Ответы [ 2 ]

0 голосов
/ 10 июля 2019

Вам нужно реализовать свой собственный конвертер, как показано ниже:

  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);
    }
    
0 голосов
/ 08 июля 2019

Я бы определил два профиля домена.Один для продукта к продуктуDto

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

И один для продукта к ценеDto

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

А затем выполните одно сопоставление за раз от одного и того же источника на две разные цели.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...