分享一个 EF6 分页查询数据的 IQueryable 扩展方法

简介: 分享一个 EF6 分页查询数据的 IQueryable 扩展方法

前言

不废话,直接上方法。_

IQueryable 扩展方法

  1. 方法一
/// <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;
}
  1. 方法一
/// <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;
}
  1. 方法说明
  • 方法一使用 EF 传统的排序方法,所以不得不根据升序或降序的需求分开来写,代码有点复杂和重复
  • 方法二利用前文所介绍的 System.Linq.Dynamic 技术,代码更加简洁可读,但性能比方法一稍微差些
  • 这两个扩展方法的思路是利用 IQueryable 的不会立即执行的特点,将具体业务数据查询跟分页展示数据解耦,提高代码的复用性和可维护性。

使用例子

  1. 方法一的使用例子
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;
}
  1. 方法二的使用例子
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 的方法,将具体业务数据查询跟分页展示数据解耦,有一定的适用性,可以将代码直接拷贝到项目中使用。

往期精彩

我是老杨,一个奋斗在一线的资深研发老鸟,让我们一起聊聊技术,聊聊程序人生,共同学习,共同进步


相关文章
|
7月前
mongoTemplate 嵌套对象包含id
mongoTemplate 嵌套对象包含id
66 0
|
SQL Java 数据库连接
Mybatis使用collection标签实现一对多关联查询,返回结果集list中嵌套list
Mybatis使用collection标签实现一对多关联查询,返回结果集list中嵌套list
573 0
|
SQL 数据库
编写SQLHelper类
编写SQLHelper类
84 1
jdbctemplate封装自定义对象,查询返回集合
jdbctemplate封装自定义对象,查询返回集合
305 0
|
SQL XML Java
MyBatis-Plus——使用查询构造器Wrapper & 简单分页操作
MyBatis-Plus——使用查询构造器Wrapper & 简单分页操作
1168 0
MyBatis-Plus——使用查询构造器Wrapper & 简单分页操作
|
SQL Java 数据库连接
Mybaits结果集之集合,Javabean中嵌套List的解决方案
Mybaits结果集之集合,Javabean中嵌套List的解决方案
239 0
Mybaits结果集之集合,Javabean中嵌套List的解决方案
|
存储 Web App开发 前端开发
EF 利用PagedList进行分页并结合查询 方法2
微软提供了PagedList分页,相信大家在网上也能搜索一大堆关于pagedList用法的博客,论坛。但是,在使用的过程中一不小心,就会掉入pagedList某种常规用法的陷阱。 我所说的某种常规用法是指如下方法(也可以参考我的博客:PagedList 分页用法): 代码如下: using System; using System.
962 0
sqlsever2008 简单分页查询例子
工资从高到低排序 输出工资是第4到6行数据 select top 3 * from emp where EMPNO not in(select top 3 EMPNO from emp order by sal des...
1157 0