只是一个用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上下文的对象提到了最上面。

 

     求指教,共同进步。

posted @ 2014-04-26 21:57  公子若不胖天下谁胖  阅读(5311)  评论(32编辑  收藏  举报