只是一個用EF寫的一個簡單的分頁方法而已


                                   只是一個用EF寫的一個簡單的分頁方法而已

           慢慢的寫吧。比如,第一步,先把所有數據查詢出來吧。      

1   //第一步。
2         public IQueryable<UserInfo> LoadPagesForUserInfos(int pageSize, int pageIndex, out int total)
3         {
4             DataModelContainer db = new DataModelContainer();
5             total = db.UserInfo.Count();
6             return db.UserInfo.Take(pageSize*(pageIndex - 1)).Skip(pageSize).AsQueryable();
7         }
第一步,先得到所有查詢數據。

      

       第二步。我總不能全查詢出來吧,我得有些條件吧。比如我要查id>18的數據。那么得用到Where()擴展方法了。那么就得這么寫了。

1  public IQueryable<UserInfo> LoadPagesInfos(int pageSize, int pageIndex, out int total)
2         {
3             DataModelContainer db = new DataModelContainer();
4             total = db.UserInfo.Where(u => u.ID > 18).Count();
5             return db.UserInfo.Where(u => u.ID > 18).Take(pageSize * (pageIndex - 1)).Take(pageSize).AsQueryable();
6         }
得有點查詢條件吧

     

      第三步,我查詢數據的條件,可能會變,比如我現在不查id>18的數據了,我要查id<100的數據或者公司名字叫“小杜的公司”的數據,你總不能老在這里給我改代碼吧。那么我們發現,其擴展方法就是傳一個委托,一個名傳入是UserInfo類型返回值是bool類型的委托,那么我們把這個委托當參數傳遞過來,讓用戶傳就好了。需要什么用戶寫好傳遞過來也就可以了。就很好的做到了對變化點的封裝。  

1    public IQueryable<UserInfo> LoadPagesForInfos(int pageSize, int pageIndex, out int total, Func<UserInfo, bool> whereFunc)
2         {
3             DataModelContainer db = new DataModelContainer();
4             total = db.UserInfo.Where(whereFunc).Count();
5             return db.UserInfo.Where(whereFunc).Skip(pageSize * (pageIndex - 1)).Take(pageSize).AsQueryable();
6         }
查詢條件讓用戶傳好不

     

      第四步,查詢條件現在是可以用戶傳遞的了,可是分頁查詢總得有一個排序吧。這樣就需要用到Order()方法了。下面代碼中的Order<UserInfo,int>(u=>u.ID)中接口是約束了這個UserInfo,而后面的int則是約束后面Lambda的返回值的。我們轉到定義就可以發現了。當然這個“<>”里的內容也是可以不寫的,此處如不寫的話是后面的Lambda表示式亦會自動推測出前面的限制是什么的。如同Skip()方法和Take()方法就沒有寫。那么,優化一下,寫一個按id排序的方法吧。

 1    public IQueryable<UserInfo> LoadPagesForInfos(int pageSize, int pageIndex, out int total,
 2             Func<UserInfo, bool> whereFunc)
 3         {
 4             DataModelContainer db = new DataModelContainer();
 5             total = db.UserInfo.Where(whereFunc).Count();
 6             return
 7                 db.UserInfo.Where(whereFunc)
 8                     .OrderBy<UserInfo, int>(u => u.ID)
 9                     .Skip(pageSize * (pageIndex - 1))
10                     .Take(pageSize)
11                     .AsQueryable();
12         }
按id排個序吧

      

      第五步,暫且就只傳遞int類型的,可是我一會是想按id>18的排序,一會是想按編號小於100的來排序,總不能按個要求就跑到這里來改代碼吧。那么這是一個變化點,可不可以封裝一下呢,讓用戶來傳遞呢,自然是可以的,依舊同上,OrderBy需要的是一個傳入的是UserInfo類型,傳出的是一個bool類型一個委托。我們將其提取出來,讓其在方法參數那里傳遞過來就可以了。

 1    public IQueryable<UserInfo> LoadPagesForInfos(int pageSize, int pageIndex, out int total,
 2             Func<UserInfo, bool> whereFunc,Func<UserInfo,int> orderByFunc )
 3         {
 4             DataModelContainer db = new DataModelContainer();
 5             total = db.UserInfo.Where(whereFunc).Count();
 6             return
 7                 db.UserInfo.Where(whereFunc)
 8                     .OrderBy<UserInfo, int>(orderByFunc)//"<>"號是可以去掉的。這里同上面是不一樣的。
 9                     .Skip(pageSize * (pageIndex - 1))
10                     .Take(pageSize)
11                     .AsQueryable();
12         }
排序條件(僅限int類型)讓用戶傳好不

   

      第六步,傳遞的值的話可能是int類型,也有可能是其他的類型,讓用戶一直傳int類型的不太合適吧。可不可以,讓用戶隨便傳遞什么類型呢。比如時間(DateTime類型)來排序,自然可以,這樣就需要用到泛型。泛型此處就不用類泛型,用方法泛型,使其職責單一,上面約束的是什么類型,下面就是什么類型。當我們對其約束之后,就是我們需要一個傳入類型是UserInfo,傳出的類型是T類型的一個委托了。依舊如上面的,我們將此委托當一個參數傳遞也就好了。就很好的做到了對此變化點的封裝了。跟第五步對比,也就是將加了一個方法泛型和OrderBy()方法對返回值的約束改成了"T"就可以了。用戶想按id來排序就傳id相應的Lambda,想按DateTime來排序就傳相應的Lambda就可以了。

 1     public IQueryable<UserInfo> LoadPagesForInfos<T>(int pageSize, int pageIndex, out int total,
 2             Func<UserInfo, bool> whereFunc, Func<UserInfo, T> orderByFunc)
 3         {
 4             DataModelContainer db = new DataModelContainer();
 5             total = db.UserInfo.Where(whereFunc).Count();
 6             return
 7                 db.UserInfo.Where(whereFunc)
 8                     .OrderBy<UserInfo, T>(orderByFunc)
 9                     .Skip(pageSize * (pageIndex - 1))
10                     .Take(pageIndex)
11                     .AsQueryable();
12         }
想怎么排就怎么排

   

       第七步,升序還是降序,排列。加個bool類型的isAsc的參數吧。小判斷一下。

 1   public IQueryable<UserInfo> LoadPagesForInfos<T>(int pageSize, int pageIndex, out int total,
 2             Func<UserInfo, bool> whereFunc, Func<UserInfo, T> orderByFunc,bool isAsc)
 3         {
 4             DataModelContainer db = new DataModelContainer();
 5             total = db.UserInfo.Where(whereFunc).Count();
 6             if (isAsc)
 7             {
 8                 return
 9                db.UserInfo.Where(whereFunc)
10                    .OrderBy<UserInfo, T>(orderByFunc)
11                    .Skip(pageSize * (pageIndex - 1))
12                    .Take(pageIndex)
13                    .AsQueryable();
14             }
15             else
16             {
17                 return
18              db.UserInfo.Where(whereFunc)
19                  .OrderByDescending<UserInfo, T>(orderByFunc)
20                  .Skip(pageSize * (pageIndex - 1))
21                  .Take(pageIndex)
22                  .AsQueryable();
23             }
24         }
升序還是降序

     

      貌似就這樣這個方法還不錯的樣子,附上一下完整方法的圖片,喜歡這個字體,我將EF上下文的對象提到了最上面。

 

     求指教,共同進步。


免責聲明!

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



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