前言
不废话,直接上方法。_
IQueryable 扩展方法
- 方法一
/// <summary> /// 由其它 Reponsitory 提供数据源,分页查询数据 /// </summary> /// <typeparam name="T"></typeparam> /// <typeparam name="S"></typeparam> /// <param name="source"></param> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <param name="whereLambda"></param> /// <param name="orderbyLambda"></param> /// <param name="total"></param> /// <param name="isAsc"></param> /// <returns></returns> public static List<T> FindPageList<T, S>(this IQueryable<T> source, int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderbyLambda, out int total, bool isAsc) { total = source.Where(whereLambda).Count(); List<T> result; if (isAsc) { result = source .Where(whereLambda) .OrderBy(orderbyLambda) .Skip(pageSize * (pageIndex - 1)) .Take(pageSize) .ToList(); } else { result = source .Where(whereLambda) .OrderByDescending(orderbyLambda) .Skip(pageSize * (pageIndex - 1)) .Take(pageSize) .ToList(); } return result; }
- 方法一
/// <summary> /// 使用动态拼接 OrderBy 语句,分页查询数据 /// </summary> /// <typeparam name="T"></typeparam> /// <param name="source"></param> /// <param name="pageIndex"></param> /// <param name="pageSize"></param> /// <param name="whereLambda"></param> /// <param name="orderbyExpression"></param> /// <param name="total"></param> /// <returns></returns> public static List<T> FindPageList<T>(this IQueryable<T> source, int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, string orderbyExpression, out int total) { total = source.Where(whereLambda).Count(); var result = source .Where(whereLambda) .OrderBy(orderbyExpression) .Skip(pageSize * (pageIndex - 1)) .Take(pageSize) .ToList(); return result; }
- 方法说明
- 方法一使用 EF 传统的排序方法,所以不得不根据升序或降序的需求分开来写,代码有点复杂和重复
- 方法二利用前文所介绍的 System.Linq.Dynamic 技术,代码更加简洁可读,但性能比方法一稍微差些
- 这两个扩展方法的思路是利用
IQueryable
的不会立即执行的特点,将具体业务数据查询跟分页展示数据解耦,提高代码的复用性和可维护性。
使用例子
- 方法一的使用例子
public List<T> QueryPageList<S>(int pageIndex, int pageSize, Expression<Func<T, bool>> whereLambda, Expression<Func<T, S>> orderbyLambda, out int total, bool isAsc) { var source = _dbContext.Set<T>().AsNoTracking().AsQueryable(); var result = source.FindPageList(pageIndex, pageSize, whereLambda, orderbyLambda, out total, isAsc); return result; } public List<TB01Dto> QueryPageList(QueryPageParams queryPageParams, out int total) { Expression<Func<TB01, bool>> whereLambda = a => !a.STSHT01.Equals("D", StringComparison.OrdinalIgnoreCase); if (!string.IsNullOrEmpty(queryPageParams.SearchKeyword)) { Expression<Func<TB01, bool>> second = (a => a.NAMEHT01.Contains(queryPageParams.SearchKeyword) || a.COMPHT01 == queryPageParams.SearchKeyword); whereLambda = whereLambda.And(second); } var list = QueryPageList(queryPageParams.PageIndex, queryPageParams.PageSize, whereLambda, (a => a.COMPHT01), out total, queryPageParams.IsAsc); var result = CommonUtil.TranObject2OtherType<List<TB01Dto>>(list); return result; }
- 方法二的使用例子
public List<UserMenuDTO> QueryPageList(QueryPageParamsForuserMenu queryPageParams, out int total) { var query = userMenuReposition.QueryMenuUsers(queryPageParams.MenuUserName); Expression<Func<UserMenuDTO, bool>> whereLambda = a => true; if (queryPageParams.CompanyCodes != null && queryPageParams.CompanyCodes.Length > 0) { Expression<Func<UserMenuDTO, bool>> second = (a => queryPageParams.CompanyCodes.Contains(a.COMPHT03)); whereLambda = whereLambda.And(second); } var list = query.FindPageList(queryPageParams.PageIndex, queryPageParams.PageSize, whereLambda, "COMPHT03, MNUCDHT03", out total); return list; }
总结
分页查询数据是在处理大量数据时常用的一种技术,对于提高系统性能,优化用户体验,节约资源,并保证系统的稳定性和安全性等方面,非常有用。本文利用 IQueryable
不会立即执行的特点,扩展了 IQueryable
的方法,将具体业务数据查询跟分页展示数据解耦,有一定的适用性,可以将代码直接拷贝到项目中使用。
往期精彩
我是老杨,一个奋斗在一线的资深研发老鸟,让我们一起聊聊技术,聊聊程序人生,共同学习,共同进步