powered by simpleCommunicator - 2.0.41     © 2025 Programmizd 02
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Automapper. Класс с коллекцией в коллекцию классов.
1 сообщений из 1, страница 1 из 1
Automapper. Класс с коллекцией в коллекцию классов.
    #39923360
Фотография X-Cite
Скрыть профиль Поместить в игнор-лист Сообщения автора в теме
Участник
Добрый день.
.Net Core 3.1 + AutoMapper 9.0.0
В первом спойлере настроил автомаппер - работает. Из минусов, придется для всех классов (примерно очень много штук прописывать ConvertUsing)
Во втором спойлере попытка этого избежать и он не работает. Собственно можно ли настроить так, чтобы упросить настройку.
Ессно полей в классах больше, чем в тестовом примере.

Рабочий способ:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
24.
25.
26.
27.
28.
29.
30.
31.
32.
33.
34.
35.
36.
37.
38.
39.
40.
41.
42.
43.
44.
45.
46.
47.
48.
49.
50.
51.
52.
53.
54.
55.
56.
57.
58.
59.
60.
61.
62.
63.
64.
65.
66.
67.
68.
69.
70.
71.
72.
73.
74.
75.
76.
77.
78.
79.
80.
81.
82.
83.
84.
85.
86.
87.
88.
89.
90.
91.
92.
93.
94.
95.
96.
97.
98.
99.
100.
101.
102.
103.
104.
105.
106.
107.
108.
109.
110.
111.
112.
113.
114.
115.
116.
117.
118.
119.
using AutoMapper;
using System;
using System.Collections.Generic;
using System.Linq;

namespace ConsoleApp12
{
    public interface ICommand
    {
        Int32 ID { get; set; }
    }

    public interface ICommand<T> : ICommand
    {
        IEnumerable<T> Items { get; set; }
    }

    public class Command : ICommand
    {
        public Int32 ID { get; set; }
    }

    public class Command<T> : Command, ICommand<T>
    {
        public IEnumerable<T> Items { get; set; }
    }

    public interface IItem { }

    public class ItemA : IItem
    {
        public String Name { get; set; }
    }

    public class ItemB : IItem
    {
        public String Name { get; set; }
    }

    public class ItemC : IItem
    {
        public String Name { get; set; }
    }

    public class CommandA : Command<ItemA> { }
    public class CommandB : Command<ItemB> { }
    public class CommandC : Command<ItemC> { }

    public class DTO
    {
        public Int32 IDID { get; set; }
        public String Name { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            var sa = new CommandA { ID = 1, Items = new List<ItemA> { new ItemA { Name = "A" }, new ItemA { Name = "B" } } };
            var sb = new CommandB { ID = 2, Items = new List<ItemB> { new ItemB { Name = "C" }, new ItemB { Name = "D" } } };
            var sc = new CommandC { ID = 3, Items = new List<ItemC> { new ItemC { Name = "E" }, new ItemC { Name = "F" } } };

            var config = new MapperConfiguration(x =>
                {
                    x.CreateMap<ICommand, DTO>()
                        .ForMember(d => d.IDID, opt => opt.MapFrom(src => src.ID));

                    x.CreateMap<ItemA, DTO>();
                    x.CreateMap<ItemB, DTO>();
                    x.CreateMap<ItemC, DTO>();

                    x.CreateMap<CommandA, IEnumerable<DTO>>()
                        .ConvertUsing( (src, dst, ctx) =>
                            src.Items.Select(s =>
                            {
                                var x = ctx.Mapper.Map<DTO>(s);
                                return ctx.Mapper.Map(src, x);
                            })
                        );

                    x.CreateMap<CommandB, IEnumerable<DTO>>()
                        .ConvertUsing((src, dst, ctx) =>
                           src.Items.Select(s =>
                           {
                               var x = ctx.Mapper.Map<DTO>(s);
                               return ctx.Mapper.Map(src, x);
                           })
                        );

                    x.CreateMap<CommandC, IEnumerable<DTO>>()
                        .ConvertUsing((src, dst, ctx) =>
                           src.Items.Select(s =>
                           {
                               var x = ctx.Mapper.Map<DTO>(s);
                               return ctx.Mapper.Map(src, x);
                           })
                        );
                }
            );
            var mapper = config.CreateMapper();
            var a = mapper.Map<CommandA, IEnumerable<DTO>>(sa);
            var b = mapper.Map<CommandB, IEnumerable<DTO>>(sb);
            var c = mapper.Map<CommandC, IEnumerable<DTO>>(sc);
            foreach (var x in a)
            {
                Console.WriteLine("{0}, {1}", x.IDID, x.Name);
            }
            foreach (var x in b)
            {
                Console.WriteLine("{0}, {1}", x.IDID, x.Name);
            }
            foreach (var x in c)
            {
                Console.WriteLine("{0}, {1}", x.IDID, x.Name);
            }
            Console.ReadKey();
        }
    }
}


Из минусов видно, что для каждой такой пары CommandA -> IEnumerable<DTO> надо писать ConvertUsing

Собственно хочется один раз его прописать для пары ICommand<IItem> -> IEnumerable<DTO> и дальше только просто указывать карту мапки для наследуемых типов.
Что-то вроде такого:
Код: c#
1.
2.
3.
4.
5.
6.
7.
8.
9.
10.
11.
12.
13.
14.
15.
16.
17.
18.
19.
20.
21.
22.
23.
                var config = new MapperConfiguration(x =>
                {
                    x.CreateMap<ICommand, DTO>()
                        .ForMember(d => d.IDID, opt => opt.MapFrom(src => src.ID));

                    x.CreateMap<ItemA, DTO>();
                    x.CreateMap<ItemB, DTO>();
                    x.CreateMap<ItemC, DTO>();

                    x.CreateMap<ICommand<IItem>, IEnumerable<DTO>>()
                        .ConvertUsing((src, dst, ctx) =>
                           src.Items.Select(s =>
                           {
                               var x = ctx.Mapper.Map<DTO>(s);
                               return ctx.Mapper.Map(src, x);
                           })
                        );

                    x.CreateMap<CommandA, IEnumerable<DTO>>();
                    x.CreateMap<CommandB, IEnumerable<DTO>>();
                    x.CreateMap<CommandC, IEnumerable<DTO>>();
                }
            );



Но это не работает и выдает ошибку Method 'GetEnumerator' in type ... does not have an implementation.'
...
Рейтинг: 0 / 0
1 сообщений из 1, страница 1 из 1
Форумы / ASP.NET [игнор отключен] [закрыт для гостей] / Automapper. Класс с коллекцией в коллекцию классов.
Целевая тема:
Создать новую тему:
Автор:
Закрыть
Цитировать
Найденые пользователи ...
Разблокировать пользователей ...
Читали форум (0):
Пользователи онлайн (0):
x
x
Закрыть


Просмотр
0 / 0
Close
Debug Console [Select Text]