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 分页查询优化的主要内容,如果未能解决你的问题,请参考以下文章