Как использовать действие BeforeMap при сопоставлении двух коллекций с помощью Automapper?

#c# #automapper

#c# #automapper

Вопрос:

При сопоставлении двух отдельных объектов с помощью automapper BeforeMap действие работает нормально:

 return _mapper.Map<Project, ProjectDto>(projects, opt =>
{
    opt.BeforeMap((src, dest) => dest.ProvidedLanguage = requestedLanguage);
});
  

Но при сопоставлении двух коллекций BeforeMap не работает так, как src и dest имеют тип object сейчас:

 return _mapper.Map<IEnumerable<Project>, IEnumerable<ProjectDto>>(projects, opt =>
{
    opt.BeforeMap((src, dest) => dest.ProvidedLanguage = requestedLanguage);
});
  

Мне нужен предоставленный язык для самого сопоставления, поэтому я не могу установить его после сопоставления. Как я могу передать предоставленный язык объектам назначения при сопоставлении двух коллекций?

Ответ №1:

Я предварительно решил это так:

         var result = new List<ProjectDto>();
        foreach (var item in projects)
        {
            var dest = new ProjectDto() { ProvidedLanguage = requestedLanguage };
            result.Add(_mapper.Map(item, dest));
        }
  

Я знаю, что это не выглядит элегантно. если кто-нибудь знает лучший способ решить эту проблему, не стесняйтесь поделиться своей идеей.

Комментарии:

1. Я пытался улучшить свой ответ, но независимо пришел к тому же решению, ха-ха.

Ответ №2:

Использование BeforeMap() для настройки объекта назначения опасно. Запуск вашего кода:

 return _mapper.Map<Project, ProjectDto>(projects, opt =>
{
    opt.BeforeMap((src, dest) => dest.ProvidedLanguage = requestedLanguage);
});
  

приведет к тому, что объект NullReferenceException as dest еще не был инициализирован AutoMapper. Смотрите, BeforeMap() лучше всего работает при выполнении некоторых настроек над исходным объектом, потому что любая работа над объектом назначения может быть переопределена предстоящим процессом сопоставления. Если вы хотите внести изменения в свой объект назначения, лучше использовать AfterMap() . Таким образом, у вас уже будет закончен процесс сопоставления и уверенность в том, что ваш целевой объект был инициализирован. Я не говорю, что вы не должны использовать BeforeMap() , я просто говорю, что будьте осторожны с этим и используйте его, когда вы действительно знаете, что делаете.

Что касается сопоставления коллекций, может показаться, что они имеют object тип, но это именно то, чем они кажутся. Установите точку останова в отладчике, чтобы убедиться, что их тип правильный.

И вы не сможете установить ProvidedLanguage свойство на IEnumerable . Если вы хотите установить это свойство для каждой, ProjectDto которая находится внутри этого IEnumerable , используйте foreach цикл для этого:

 return _mapper.Map<IEnumerable<Project>, IEnumerable<ProjectDto>>(projects, opt =>
{
    opt.AfterMap((source, destination) =>
    {
        foreach (var dto in destination)
        {
            dto.ProvidedLanguage = requestedLanguage;
        }
    });
});
  

Комментарии:

1. Спасибо за ваш ответ. Суть в том, что мне нужен запрошенный язык во время сопоставления, поэтому его установка после сопоставления, к сожалению, мне не поможет