EF 分页查询优化

Posted Mr.石

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了EF 分页查询优化相关的知识,希望对你有一定的参考价值。

按照通常的方式分页查询至少要查询数据两遍,一个操作是查询总数,另一个是查询数据,这样有些耗时

这里介绍一个基于EF的插件 EntityFramework.Extended,当然这个插件有很多的功能,比方说批量删除、批量修改、批量查询、缓存查询等

这里只介绍批量查询的方法

通过SQL Server Profilter监视生成的SQL代码,发现只连接了一次数据库,非常的厉害

 


不解释直接上代码

通用分页查询方法:

复制代码
 1         /// <summary>
 2         /// 分页查询
 3         /// </summary>
 4         /// <typeparam name="TKey">排序类型</typeparam>
 5         /// <param name="pageIndex">当前页</param>
 6         /// <param name="pageSize">每页大小</param>
 7         /// <param name="isAsc">是否升序排列</param>
 8         /// <param name="predicate">条件表达式</param>
 9         /// <param name="keySelector">排序表达式</param>
10         /// <returns></returns>
11         public virtual IPage<TEntity> Page<TKey>(int pageIndex, int pageSize, Expression<Func<TEntity, bool>> predicate, bool isAsc,
12             Expression<Func<TEntity, TKey>> keySelector)
13         {
14             if (pageIndex <= 0 && pageSize <= 0)
15             {
16                 throw new Exception("pageIndex或pageSize不能小于等于0!");
17             }
18             IPage<TEntity> page = new Page<TEntity>()
19             {
20                 PageIndex = pageIndex,
21                 PageSize = pageSize
22             };
23             int skip = (pageIndex - 1) * pageSize;
24             if (predicate == null)
25             {
26                 FutureCount fcount = this.dbSet.FutureCount();
27                 FutureQuery<TEntity> futureQuery = isAsc 
28                     ? this.dbSet.OrderBy(keySelector).Skip(skip).Take(pageSize).Future() 
29                     : this.dbSet.OrderByDescending(keySelector).Skip(skip).Take(pageSize).Future();
30                 page.TotalItems = fcount.Value;
31                 page.Items = futureQuery.ToList();
32                 page.TotalPages = page.TotalItems / pageSize;
33                 if ((page.TotalItems % pageSize) != 0) page.TotalPages++;
34             }
35             else
36             {
37                 var queryable = this.dbSet.Where(predicate);
38                 FutureCount fcount = queryable.FutureCount();
39                 FutureQuery<TEntity> futureQuery = isAsc
40                     ? queryable.OrderBy(keySelector).Skip(skip).Take(pageSize).Future()
41                     : queryable.OrderByDescending(keySelector).Skip(skip).Take(pageSize).Future();
42                 page.TotalItems = fcount.Value;
43                 page.Items = futureQuery.ToList();
44                 page.TotalPages = page.TotalItems / pageSize;
45                 if ((page.TotalItems % pageSize) != 0) page.TotalPages++;
46             }
47             return page;
48         }
复制代码

 

 分页实体:

复制代码
 1     /// <summary>
 2     /// 分页实体
 3     /// </summary>
 4     /// <typeparam name="T">实体</typeparam>
 5     public class Page<T> : IPage<T>
 6     {
 7         /// <summary>
 8         /// 当前页
 9         /// </summary>
10         public int PageIndex { get; set; }
11         /// <summary>
12         /// 总页数
13         /// </summary>
14         public int TotalPages { get; set; }
15         /// <summary>
16         /// 查询集合总个数
17         /// </summary>
18         public int TotalItems { get; set; }
19         /// <summary>
20         /// 每页项数
21         /// </summary>
22         public int PageSize { get; set; }
23         /// <summary>
24         /// 查询集合
25         /// </summary>
26         public IList<T> Items { get; set; }
27     }
28 
29     /// <summary>
30     /// 分页实体接口
31     /// </summary>
32     /// <typeparam name="T">实体</typeparam>
33     public interface IPage<T>
34     {
35         /// <summary>
36         /// 当前页
37         /// </summary>
38         int PageIndex { get; set; }
39         /// <summary>
40         /// 总页数
41         /// </summary>
42         int TotalPages { get; set; }
43         /// <summary>
44         /// 查询集合总个数
45         /// </summary>
46         int TotalItems { get; set; }
47         /// <summary>
48         /// 每页项数
49         /// </summary>
50         int PageSize { get; set; }
51         /// <summary>
52         /// 查询集合
53         /// </summary>
54         IList<T> Items { get; set; }
55     }
复制代码

以上是关于EF 分页查询优化的主要内容,如果未能解决你的问题,请参考以下文章

EF 利用PagedList进行分页并结合查询 方法2

MySQL 百万级分页优化(Mysql千万级快速分页)

javaEE 分页功能最终代码优化

如何从分页的 ef 核心查询中获取可用的总行数

使用EF关于分页查询时遇到的一点疑问

mysql优化---订单查询优化:异步分页处理