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