Кто нибудь может поделиться опытом, как мапить PagedList на PagedList с AutoMapper?
Я пытаюсь следовать этому ответу. Но то что там предложено, не работает. Или я не понимаю до конца, как оно должно работать. Итак, у меня задача. Смапить PagedList объектов бизнес-логики на PagedList объектов view модели.
Вот мой метод действия контроллера:
public async Task<IActionResult> Index(int pageNumber = 1, bool showActive = true)
{
var manuallySendings = _dbContext.ManuallySendings
.Include(x => x.Messages)
.ThenInclude(x => x.PushLang).Where(x => x.IsActive == showActive);
var manuallySendingsPagedList = await manuallySendings.ToPagedListAsync(pageNumber, 15);
var viewModelsPagedList = _mapper.Map<IPagedList<ManuallySending>, IPagedList<ManuallySendingIndexViewModel>>(manuallySendingsPagedList);
return View(viewModelsPagedList);
}
Вот профайл для мапинга бизнес-объекта на модель представления
public class ManuallySendingToManuallySendingIndexPageItem : Profile
{
public ManuallySendingToManuallySendingIndexPageItem()
{
CreateMap<ManuallySending, ManuallySendingIndexViewModel>()
.ForMember(dest => dest.PackageIds,
opt
=> opt.MapFrom(x => x.PackageIds))
// more .ForMember ...
.ConvertUsing<PagedListConverter>();
}
}
И, обратите внимание, на вызов в конце ConvertUsing. Он же должен объяснить автомапперу, как мапить этот тип, верно?
А вот мой кстомный конвертор:
public class PagedListConverter : ITypeConverter<PagedList<ManuallySending>,PagedList<ManuallySendingIndexViewModel>>
{
public PagedList<ManuallySendingIndexViewModel> Convert(PagedList<ManuallySending> source,
PagedList<ManuallySendingIndexViewModel> destination, ResolutionContext context)
{
var vm = source.Select(m
=> context.Mapper.Map<ManuallySending, ManuallySendingIndexViewModel>(m)).ToList();
return new PagedList<ManuallySendingIndexViewModel>(vm, source.PageNumber, source.PageSize);
}
}
Но я даже запустить это не могу. IDE говорит мне:
ManuallySendingToManuallySendingIndexPageItem.cs(18, 18): [CS0311] Тип "AdminPanel.Automapper.PagedListConverter" не может быть использован как параметр типа "TTypeConverter" в универсальном типе или методе "IMappingExpressionBase>.ConvertUsing()". Нет преобразования неявной ссылки из "AdminPanel.Automapper.PagedListConverter" в "AutoMapper.ITypeConverter".
Нажимаю alt + enter пользуюсь подсказкой. Мне предлагается изменить интерфейс конвертора с ITypeConverter<PagedList<ManuallySending>,PagedList<ManuallySendingIndexViewModel>> на ITypeConverter<ManuallySending, ManuallySendingIndexViewModel>
Но как я из этого сделаю PagedList? Не понимаю :( Помогите, пожалуйста. Думаю, решение поможет многим, кто на это наткнется в дальнейшем.
P.S Я использую автомаппер последней версии и .net core 3.1. Все самое новое.
Ответы (1 шт):
Итак, после некоторого ресерча и микса нескольких решений со SO я пришел вот к такому "дженерик" конвертору и способу его использования.
1) Обязательно иметь обычный профайлер business object -> view model object. Смотрите подробности в документации вот ссылка.
2) Сделаем еще один профайлер, где объясним мапперу, что мы хотим не просто эти объекты мапить, а их paged листы. Согласно моему нейменгу и коду из вопроса, он у меня выглядит так:
public class PagedListToPagedList : Profile
{
public PagedListToPagedList()
{
CreateMap<IPagedList<ManuallySending>, IPagedList<ManuallySendingIndexViewModel>>()
.ConvertUsing<PagedListConverter<ManuallySending, ManuallySendingIndexViewModel>>();
}
}
3) А теперь самое интересное. Видите, мы тут сказали автомапперу, что конвертр будем использовать? (вызов ConvertUsing). Напишем этот дженерик конвертр. Он у меня вот такой получился.
public class
PagedListConverter<TSource, TDestination> : ITypeConverter<IPagedList<TSource>, IPagedList<TDestination>>
where TSource : class where TDestination : class
{
public IPagedList<TDestination> Convert(IPagedList<TSource> source,
IPagedList<TDestination> destination, ResolutionContext context)
{
var vm = source.Select(m
=> context.Mapper.Map<TSource, TDestination>(m)).ToList();
return new StaticPagedList<TDestination>(vm, source.GetMetaData());
}
}
В отличии о того способа, что указан по ссылке на англоязычный SO в моем вопросе, тут у меня не теряется количество страниц и пагинация отрабатывает корректно! Всем спасибо, надеюсь, что это кому то поможет!