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     }
復制代碼


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM