Automapper可以映射分页列表吗?

我想使用以下内容将页面的业务对象列表映射到视图模型对象的分页列表:

var listViewModel = _mappingEngine.Map<IPagedList, IPagedList>(requestForQuotes); 

分页列表实现类似于Rob Conery在此处的实现: http : //blog.wekeroad.com/2007/12/10/aspnet-mvc-pagedlistt/

如何设置Automapper来执行此操作?

AutoMapper不支持开箱即用,因为它不知道IPagedList<>任何实现。 但是你有两个选择:

  1. 使用现有的Array / EnumerableMappers作为指南编写自定义IObjectMapper 。 这是我亲自去的方式。

  2. 编写自定义TypeConverter,使用:

     Mapper .CreateMap, IPagedList>() .ConvertUsing(); 

    并在里面使用Mapper.Map来映射列表的每个元素。

使用jrummell的答案,我创建了一个与Troy Goode的PagedList一起使用的扩展方法。 它让你不必在任何地方放置如此多的代码……

  public static IPagedList ToMappedPagedList(this IPagedList list) { IEnumerable sourceList = Mapper.Map, IEnumerable>(list); IPagedList pagedResult = new StaticPagedList(sourceList, list.GetMetaData()); return pagedResult; } 

用法是:

 var pagedDepartments = database.Departments.OrderBy(orderBy).ToPagedList(pageNumber, pageSize).ToMappedPagedList(); 

如果你正在使用Troy Goode的 StaticPagedList ,那么有一个StaticPagedList类可以帮助你映射。

 // get your original paged list IPagedList pagedFoos = _repository.GetFoos(pageNumber, pageSize); // map to IEnumerable IEnumerable bars = Mapper.Map>(pagedFoos); // create an instance of StaticPagedList with the mapped IEnumerable and original IPagedList metadata IPagedList pagedBars = new StaticPagedList(bars, pagedFoos.GetMetaData()); 

我在AutoMapper周围创建了一个小包装器,将PagedList映射到PagedList

 public class MappingService : IMappingService { public static Func AutoMap = (a, b, c) => { throw new InvalidOperationException( "The Mapping function must be set on the MappingService class"); }; public PagedList MapToViewModelPagedList(PagedList model) { var mappedList = MapPagedListElements(model); var index = model.PagerInfo.PageIndex; var pageSize = model.PagerInfo.PageSize; var totalCount = model.PagerInfo.TotalCount; return new PagedList(mappedList, index, pageSize, totalCount); } public object Map(TSource model) { return AutoMap(model, typeof(TSource), typeof(TDestination)); } public object Map(object source, Type sourceType, Type destinationType) { if (source is IPagedList) { throw new NotSupportedException( "Parameter source of type IPagedList is not supported. Please use MapToViewModelPagedList instead"); } if (source is IEnumerable) { IEnumerable input = ((IEnumerable)source).OfType(); Array a = Array.CreateInstance(destinationType.GetElementType(), input.Count()); int index = 0; foreach (object data in input) { a.SetValue(AutoMap(data, data.GetType(), destinationType.GetElementType()), index); index++; } return a; } return AutoMap(source, sourceType, destinationType); } private static IEnumerable MapPagedListElements(IEnumerable model) { return model.Select(element => AutoMap(element, typeof(TSourceElement), typeof(TDestinationElement))).OfType(); } } 

用法:

 PagedList
pagedlist = repository.GetPagedList(page, pageSize); mappingService.MapToViewModelPagedList(pagedList);

重要的是你必须使用元素类型!

如果您有任何问题或建议,请随时评论:)

AutoMapper自动处理几种类型的列表和数组之间的转换: http ://automapper.codeplex.com/wikipage?title = List%20and%20Arrays

它似乎不会自动转换从IListinheritance的自定义类型的列表,但解决方法可能是:

  var pagedListOfRequestForQuote = new PagedList( AutoMapper.Mapper.Map, List>(((List)requestForQuotes), page ?? 1, pageSize 

我需要使用支持ASP.NET Web API的IMapper接口的AutoMapper版本6.0.2返回可序列化版本的IPagedList<> 。 那么,如果问题是我如何支持以下内容:

 //Mapping from an enumerable of "foo" to a different enumerable of "bar"... var listViewModel = _mappingEngine.Map, PagedViewModel>(requestForQuotes); 

然后人们可以这样做:

定义PagedViewModel
来源: AutoMapper自定义类型转换器无法正常工作

 public class PagedViewModel { public int FirstItemOnPage { get; set; } public bool HasNextPage { get; set; } public bool HasPreviousPage { get; set; } public bool IsFirstPage { get; set; } public bool IsLastPage { get; set; } public int LastItemOnPage { get; set; } public int PageCount { get; set; } public int PageNumber { get; set; } public int PageSize { get; set; } public int TotalItemCount { get; set; } public IEnumerable Subset { get; set; } } 

将开放式通用转换器从IPagedList写入PagedViewModel
资料来源: https : //github.com/AutoMapper/AutoMapper/wiki/Open-Generics

 public class Converter : ITypeConverter, PagedViewModel> { public PagedViewModel Convert(IPagedList source, PagedViewModel destination, ResolutionContext context) { return new PagedViewModel() { FirstItemOnPage = source.FirstItemOnPage, HasNextPage = source.HasNextPage, HasPreviousPage = source.HasPreviousPage, IsFirstPage = source.IsFirstPage, IsLastPage = source.IsLastPage, LastItemOnPage = source.LastItemOnPage, PageCount = source.PageCount, PageNumber = source.PageNumber, PageSize = source.PageSize, TotalItemCount = source.TotalItemCount, Subset = context.Mapper.Map, IEnumerable>(source) //User mapper to go from "foo" to "bar" }; } } 

配置映射器

 new MapperConfiguration(cfg => { cfg.CreateMap();//Define each object you need to map cfg.CreateMap(typeof(IPagedList<>), typeof(PagedViewModel<>)).ConvertUsing(typeof(Converter<,>)); //Define open generic mapping });