问题描述

系统中实现了一个自定义的PagedList

/// <summary>
/// Paged list interface
/// </summary>
public interface IPagedList
{
int PageIndex { get; }
int PageSize { get; }
int TotalCount { get; }
int TotalPages { get; }
bool HasPreviousPage { get; }
bool HasNextPage { get; }
} /// <summary>
/// Paged list interface
/// </summary>
public interface IPagedList<T> : IList<T>, IPagedList
{
} /// <summary>
/// Paged list
/// </summary>
/// <typeparam name="T">T</typeparam>
[Serializable]
public class PagedList<T> : List<T>, IPagedList<T>
{
/// <summary>
/// Ctor
/// </summary>
/// <param name="source">source</param>
/// <param name="pageIndex">Page index</param>
/// <param name="pageSize">Page size</param>
public PagedList(IQueryable<T> source, int pageIndex, int pageSize)
{
int total = source.Count();
this.TotalCount = total;
this.TotalPages = total / pageSize; if (total % pageSize > 0)
TotalPages++; this.PageSize = pageSize;
this.PageIndex = pageIndex;
this.AddRange(source.Skip(pageIndex * pageSize).Take(pageSize).ToList());
} /// <summary>
/// Ctor
/// </summary>
/// <param name="source">source</param>
/// <param name="pageIndex">Page index</param>
/// <param name="pageSize">Page size</param>
public PagedList(IList<T> source, int pageIndex, int pageSize)
{
TotalCount = source.Count();
TotalPages = TotalCount / pageSize; if (TotalCount % pageSize > 0)
TotalPages++; this.PageSize = pageSize;
this.PageIndex = pageIndex;
this.AddRange(source.Skip(pageIndex * pageSize).Take(pageSize).ToList());
} /// <summary>
/// Ctor
/// </summary>
/// <param name="source">source</param>
/// <param name="pageIndex">Page index</param>
/// <param name="pageSize">Page size</param>
/// <param name="totalCount">Total count</param>
public PagedList(IEnumerable<T> source, int pageIndex, int pageSize, int totalCount)
{
TotalCount = totalCount;
TotalPages = TotalCount / pageSize; if (TotalCount % pageSize > 0)
TotalPages++; this.PageSize = pageSize;
this.PageIndex = pageIndex;
this.AddRange(source);
} public int PageIndex { get; private set; }
public int PageSize { get; private set; }
public int TotalCount { get; private set; }
public int TotalPages { get; private set; } public bool HasPreviousPage
{
get { return (PageIndex > 0); }
}
public bool HasNextPage
{
get { return (PageIndex + 1 < TotalPages); }
}
}

转换失败,AutoMapper可不认识PagedList

 [TestMethod]
public void MapTest2()
{
Mapper.CreateMap<User, UserViewModel>(); var userList = new List<User>()
{
new User() {Name = "Name1", UserId = "UserId1"},
new User() {Name = "Name2", UserId = "UserId2"},
new User() {Name = "Name3", UserId = "UserId3"},
new User() {Name = "Name4", UserId = "UserId4"},
new User() {Name = "Name5", UserId = "UserId5"},
new User() {Name = "Name6", UserId = "UserId6"},
new User() {Name = "Name7", UserId = "UserId7"},
}; var pagedList = new PagedList<User>(userList, 0, 5); Mapper.Map<PagedList<User>, PagedList<UserViewModel>>(pagedList);//Exception }

解决方案

 /// <summary>
/// The collection extensions.
/// </summary>
public static class ObjectExtensions
{
private static readonly MethodInfo mapMethod;
private static readonly ConcurrentDictionary<Tuple<Type, Type>, Tuple<MethodInfo, Type>> methodsMapper = new ConcurrentDictionary<Tuple<Type, Type>, Tuple<MethodInfo, Type>>(); static ObjectExtensions()
{
mapMethod = (typeof(Mapper)).GetMethods().FirstOrDefault(_ => _.Name == "Map" && _.GetParameters().Length == 1);
} public static T MapTo<T>(this IPagedList tList) where T : class
{
var totalCount = tList.TotalCount;
var pageIndex = tList.PageIndex;
var pageSize = tList.PageSize; var t = methodsMapper.GetOrAdd(new Tuple<Type, Type>(tList.GetType(), typeof(T)), _ =>
{
var targetGenericArguments = typeof(T).GenericTypeArguments[0];
var targetGenericArgumentsIEnumerableType = typeof(IEnumerable<>).MakeGenericType(targetGenericArguments);
return new Tuple<MethodInfo, Type>(mapMethod.MakeGenericMethod(targetGenericArgumentsIEnumerableType),
typeof(PagedList<>).MakeGenericType(targetGenericArguments));
});
var rtn2 = t.Item1.Invoke(null, new object[] { tList });
var o2 = Activator.CreateInstance(t.Item2, rtn2, pageIndex, pageSize, totalCount) as T;
return o2;
} public static T MapTo<T>(this object o) where T : class
{
//way1
//var mapMethod = (typeof(Mapper)).GetMethods().FirstOrDefault(_ => _.Name == "Map" && _.GetParameters().Length == 1 && _.GetGenericArguments().Length == 2 );
//var m2 = mapMethod.MakeGenericMethod(o.GetType(), typeof (T));
//return m2.Invoke(null, new[] { o }) as T; //way2
return Mapper.Map<T>(o);
} public static void MapTo<S,T>(this S o,T t) where T : class
{
Mapper.Map(o,t);
}
}

测试通过

[TestMethod]
public void MapTest2()
{
Mapper.CreateMap<User, UserViewModel>(); var userList = new List<User>()
{
new User() {Name = "Name1", UserId = "UserId1"},
new User() {Name = "Name2", UserId = "UserId2"},
new User() {Name = "Name3", UserId = "UserId3"},
new User() {Name = "Name4", UserId = "UserId4"},
new User() {Name = "Name5", UserId = "UserId5"},
new User() {Name = "Name6", UserId = "UserId6"},
new User() {Name = "Name7", UserId = "UserId7"},
}; var pagedList = new PagedList<User>(userList, 0, 5);
var vmPagedList = pagedList.MapTo<PagedList<UserViewModel>>();
Assert.IsTrue(vmPagedList.TotalPages == 2
&& vmPagedList.PageSize == 5
&& vmPagedList.PageIndex == 0
); }

总结

运行时动态获取泛型参数并执行Mapper.Map<IEnumerable<TSource>, IEnumerable<TDestination>>,并且使用ConcurrentDictionary缓存MethodInfo提高性能。

最新文章

  1. C#高级编程笔记 Delegate 的粗浅理解 2016年9月 13日
  2. 通过淘宝IP地址库获取IP位置
  3. Apple Watch已向微信开放WatchKit接口?
  4. IM即时通讯实现原理
  5. 嵌入式Linux应用开发——Linux下的C编程基础
  6. 如何调节datagridview中字体
  7. size()函数的使用
  8. C#垃圾回收
  9. (原+转)ubuntu中删除文件夹
  10. SQL Server2012中的SequenceNumber
  11. oracle导入dmp数据库文件
  12. NYOJ-915 +-字符串(贪心)
  13. mysql建表: 主键,外键约束
  14. python学习:输入设置
  15. 洛谷 P1101 单词方阵
  16. 0003-20180422-自动化第三章-python基础学习笔记
  17. JVM规范系列第3章:为Java虚拟机编译
  18. angular.js的依赖注入解析
  19. JavaWeb总结(九)
  20. (GoRails)ActiveRecord --explain方法:(优化你的查询)

热门文章

  1. 完成端口(Completion Port)详解(转)
  2. SQL设置SQLServer最大连接数查询语句
  3. 使用 crosswalk-cordova 打包sencha touch 项目,再也不用担心安卓兼容问题!
  4. ux.plup.File plupload 集成 ux.plup.FileLis 批量上传预览
  5. 安卓TTS语音合成经验分享(科大讯飞语音+)集成
  6. 基于Java的数据采集(终结篇)
  7. Android View的加载过程
  8. zk框架window之间传值操作
  9. Visual Studio .NET项目转换器(ProjectConverter)修改
  10. Webkit CSS properties