前言
不废话,直接上方法。_
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
的方法,将具体业务数据查询跟分页展示数据解耦,有一定的适用性,可以将代码直接拷贝到项目中使用。
往期精彩
- 不会使用 EF Core 的 Code First 模式?来看看这篇文章,手把手地教你
- EF Core 性能很差?试试这 6 个小技巧
- 如何在 EF Core 中使用乐观并发控制
- EF Core 在实际开发中,如何分层?
我是老杨,一个奋斗在一线的资深研发老鸟,让我们一起聊聊技术,聊聊程序人生,共同学习,共同进步