Сопоставление списков с использованием Automapper

#asp.net-mvc #automapper

#asp.net-mvc #automapper

Вопрос:

У меня есть классы:

 public class Person{ /* Props here */ }

public class PersonViewModel { /* Props here */ }
  

Затем список:

 List<Person> people = new List<Person>();
List<PersonViewModel> peopleVM = Mapper
                                .MapList<Person, PersonViewModel>(people); //Problem here.
  

Каков правильный способ сделать это?

Ответ №1:

 Mapper.CreateMap<Person, PersonViewModel>();
peopleVM = Mapper.Map<List<Person>, List<PersonViewModel>>(people);
Mapper.AssertConfigurationIsValid();
  

Из начала:

Как мне использовать AutoMapper?

Во-первых, вам нужен как исходный, так и целевой тип для работы. На дизайн целевого типа может влиять уровень, в котором он находится, но AutoMapper работает лучше всего, если имена элементов совпадают с именами элементов исходного типа. Если у вас есть исходный элемент с именем «FirstName», он будет автоматически сопоставлен целевому элементу с именем «FirstName». AutoMapper также поддерживает выравнивание, которое позволяет избавиться от всех этих надоедливых исключений нулевой ссылки, с которыми вы можете столкнуться на этом пути.

Получив нужные типы и ссылку на AutoMapper, вы можете создать сопоставление для двух типов.

 Mapper.CreateMap<Order, OrderDto>();
  

Тип слева — это тип источника, а тип справа — тип назначения. Для выполнения сопоставления используйте метод Map.

 OrderDto dto = Mapper.Map<Order, OrderDto>(order);
  

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

1. Нужно ли мне использовать CreateMap? Я использовал automapper без него, и он работает.

2. Вероятно, не до тех пор, пока имена свойств совпадают, и ему не нужно ничего преобразовывать. Вы можете использовать create map, если имена свойств не совпадают или вы хотите игнорировать свойства и т.д.

3. Попробуйте добавить команду создать карту. Вы также можете использовать Mapper. AssertConfigurationIsValid(); после создания. Обычно вы помещаете все свои создания в bootstrapper или функцию запуска. AutoMapper также поддерживает профили.

4. Существует ли какой-либо короткий метод для создания сопоставления в обоих направлениях друг с другом? Mapper.Map<List<Person>, List<PersonViewModel>>(person) и Mapper.Map<List<PersonViewModel> ,List<Person>>(person)

5. @doganak Mapper.Map<Список<персона>, Список<PersonViewModel>> (персона). ReverseMap()

Ответ №2:

Другое решение

 List<Person> people = new List<Person>();
List<PersonViewModel> peopelVM;
peopelVM = people.Select(Mapper.Map<Person, PersonViewModel>);
  

И в конфигурации Automapper

 Mapper.CreateMap<Person, PersonViewModel>();
  

Ответ №3:

Если вы используете здесь IQueryable списки (например, из EF или NH), вы можете использовать AutoMapper.IQueryableExtensions методы, Project() и To() .

Я впервые использую AutoMapper, но мне удается создать карту только для модели:

 Mapper.CreateMap<Person, PersonViewModel>();
Mapper.AssertConfigurationIsValid();
  

А затем с помощью IQueryableExtension методов Project() и To() :

 using AutoMapper.QueryableExtensions;
...

IQueryable<Person> people = new List<Person>().AsQueryable(); //actually from ORM
IQueryable<PersonViewModel> peopleVM = people.Project().To<PersonViewModel>();
  

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

1. Я нахожу этот ответ наиболее полезным / элегантным. Однако, Project() теперь устарел и должен быть заменен на ProjectTo() .

Ответ №4:

В ядре 1.1 это расширение может работать:

 public static List<TDestination> MapList<TSource, TDestination>(this IMapper mapper, List<TSource> source)
        {
            return source.Select(x => mapper.Map<TDestination>(x)).ToList();
        }
  

Ответ №5:

Другое решение

 mapper.Map<IEnumerable<PersonViewModel>>(people);
  

Ответ №6:

Вы могли бы создать метод расширения, чтобы сделать что-то подобное, используя существующие сопоставления для отдельных элементов:

 public static class AutoMapperExtensions
{
    public static List<TDestination> MapList<TSource, TDestination>(this IMapper mapper, List<TSource> source)
    {
        return mapper.Map<List<TDestination>>(source);
    }
}
  

Использование:

 List<PersonViewModel> peopleVM = _mapper.MapList<PersonViewModel>(people);