自动映射器可以映射分页列表吗?
我想用这样的业务对象的分页目录映射到视图模型对象的分页列表:自动映射器可以映射分页列表吗?
var listViewModel = _mappingEngine.Map<IPagedList<RequestForQuote>, IPagedList<RequestForQuoteViewModel>>(requestForQuotes);
的分页列表实现类似于罗布科纳的实现在这里: http://blog.wekeroad.com/2007/12/10/aspnet-mvc-pagedlistt/
如何设置Automapper来执行此操作?
AutoMapper不支持开箱即用,因为它不知道IPagedList<>
的任何实现。然而,你有两个选择:
编写自定义
IObjectMapper
,利用现有的磁盘阵列/ EnumerableMappers作为指导。这是我个人的方式。-
编写自定义类型转换器,使用:
Mapper .CreateMap<IPagedList<Foo>, IPagedList<Bar>>() .ConvertUsing<MyCustomTypeConverter>();
和内部使用
Mapper.Map
到列表中的每个元素映射。
AutoMapper几种类型的列表和阵列之间自动处理转换: http://automapper.codeplex.com/wikipage?title=Lists%20and%20Arrays
它不会出现自动转换自IList继承名单的自定义类型,但周围的工作可能是:
var pagedListOfRequestForQuote = new PagedList<RequestForQuoteViewModel>(
AutoMapper.Mapper.Map<List<RequestForQuote>, List<RequestForQuoteViewModel>>(((List<RequestForQuote>)requestForQuotes),
page ?? 1,
pageSize
此方法失去'StartRecordIndex','EndRecordIndex','TotalItemCount'和'TotalPageCount'性质。 – 2012-09-12 12:32:51
我在AutoMapper上创建了一个小包装,将PagedList<DomainModel>
映射到PagedList<ViewModel>
。
public class MappingService : IMappingService
{
public static Func<object, Type, Type, object> AutoMap = (a, b, c) =>
{
throw new InvalidOperationException(
"The Mapping function must be set on the MappingService class");
};
public PagedList<TDestinationElement> MapToViewModelPagedList<TSourceElement, TDestinationElement>(PagedList<TSourceElement> model)
{
var mappedList = MapPagedListElements<TSourceElement, TDestinationElement>(model);
var index = model.PagerInfo.PageIndex;
var pageSize = model.PagerInfo.PageSize;
var totalCount = model.PagerInfo.TotalCount;
return new PagedList<TDestinationElement>(mappedList, index, pageSize, totalCount);
}
public object Map<TSource, TDestination>(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<object> input = ((IEnumerable)source).OfType<object>();
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<TDestinationElement> MapPagedListElements<TSourceElement, TDestinationElement>(IEnumerable<TSourceElement> model)
{
return model.Select(element => AutoMap(element, typeof(TSourceElement), typeof(TDestinationElement))).OfType<TDestinationElement>();
}
}
用法:
PagedList<Article> pagedlist = repository.GetPagedList(page, pageSize);
mappingService.MapToViewModelPagedList<Article, ArticleViewModel>(pagedList);
它,你将不得不使用元素类型是很重要的!
如果您有任何问题或建议,请随时发表评论:)
如果您使用Troy Goode's PageList,有一个StaticPagedList
类,它可以帮助你进行映射。
// get your original paged list
IPagedList<Foo> pagedFoos = _repository.GetFoos(pageNumber, pageSize);
// map to IEnumerable
IEnumerable<Bar> bars = Mapper.Map<IEnumerable<Bar>>(pagedFoos);
// create an instance of StaticPagedList with the mapped IEnumerable and original IPagedList metadata
IPagedList<Bar> pagedBars = new StaticPagedList<Bar>(bars, pagedFoos.GetMetaData());
使用jrummell的回答,我创建了以Troy Goode's PagedList工作的扩展方法。它使你不必到处放这么多的代码...
public static IPagedList<TDestination> ToMappedPagedList<TSource, TDestination>(this IPagedList<TSource> list)
{
IEnumerable<TDestination> sourceList = Mapper.Map<IEnumerable<TSource>, IEnumerable<TDestination>>(list);
IPagedList<TDestination> pagedResult = new StaticPagedList<TDestination>(sourceList, list.GetMetaData());
return pagedResult;
}
用法为:
var pagedDepartments = database.Departments.OrderBy(orderBy).ToPagedList(pageNumber, pageSize).ToMappedPagedList<Department, DepartmentViewModel>();
我需要返回IPagedList<>
与AutoMapper版本6.0.2序列化的版本,支持IMapper
ASP.NET Web API的接口。因此,如果这个问题是我怎么支持以下内容:
//Mapping from an enumerable of "foo" to a different enumerable of "bar"...
var listViewModel = _mappingEngine.Map<IPagedList<RequestForQuote>, PagedViewModel<RequestForQuoteViewModel>>(requestForQuotes);
那么可以这样做:
定义PagedViewModel<T>
来源:AutoMapper Custom Type Converter not working
public class PagedViewModel<T>
{
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<T> Subset { get; set; }
}
写打开通用转换器从IPagedList<T>
到PagedViewModel<T>
来源:https://github.com/AutoMapper/AutoMapper/wiki/Open-Generics
public class Converter<TSource, TDestination> : ITypeConverter<IPagedList<TSource>, PagedViewModel<TDestination>>
{
public PagedViewModel<TDestination> Convert(IPagedList<TSource> source, PagedViewModel<TDestination> destination, ResolutionContext context)
{
return new PagedViewModel<TDestination>()
{
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<TSource>, IEnumerable<TDestination>>(source) //User mapper to go from "foo" to "bar"
};
}
}
配置映射器
new MapperConfiguration(cfg =>
{
cfg.CreateMap<RequestForQuote, RequestForQuoteViewModel>();//Define each object you need to map
cfg.CreateMap(typeof(IPagedList<>), typeof(PagedViewModel<>)).ConvertUsing(typeof(Converter<,>)); //Define open generic mapping
});
有人可以提供一个坚实的'PagedListTypeConverter'实现吗? – 2012-09-12 12:52:09
特洛伊古德的PagedList工作TypeConverter成一个简单的ViewModel可以在这里找到:http://stackoverflow.com/questions/12470156/automapper-custom-type-converter-not-working/12538611#12538611 – 2012-09-21 21:49:05