分页大杂烩
文章中提到了Linq,所以先介绍一下它,好让我们有个初步认识:
• Linq是语言级集成查询(Language INtegrated Query)
• Linq是一种用来进行数据访问的编程模型,使得.NET语言可以直接支持数据查询
• Linq发布于.net framework 3.5
• Linq体现了面向对象编程思想
• Linq包含了Linq To Sql, Linq To Entities, Linq To DataSets(这三个都体现在ADO.NET上), Linq To Objects, Linq To XML
下面是不同的分页code
1. Linq To Entity
int pageIndex = 1;
int pageSize = 30;
int skipCount = (pageIndex - 1) * pageSize;
using (GuakaoEntities db = new GuakaoEntities()) { var query = db.Info .OrderBy(m => m.ID) .Skip(skipCount) .Take(pageSize) .ToList(); var pageList = query as List<Info>; }
这是原生的linq to entity分页语句。
2. Linq To Entity之ToPageList()
int pageIndex = 1;
int pageSize = 30;
using (GuakaoEntities db = new GuakaoEntities()) { var query = from c in db.Info select c; query = query.OrderBy(m => m.ID); var pagelist = query.ToPagedList(pageIndex, pageSize); }
ToPagedList()是linq to entity分页的扩展方法。微软提供了PagedList类库,里面提供了这个扩展方法。
用SQL Server Profiler跟踪前两者生成的sql语句:
说明:OFFSET...FETCH是Sql Server 2012的新特性,OFFSET...FETCH从结果集中取出某一页的结果。ROWS可用ROW来代替,NEXT可用FIRST来代替。
例子:跳过前30行且取剩余行
select * from Info order by ID desc offset 30 rows
跳过前30行且取接下来的30行
select * from Info order by ID desc offset 30 rows fetch next 30 rows only
限制条件:
offset...fetch要与order by一起使用;
top和offset...fetch不能在同一个表达式中一起使用;
3. Linq To SQL
private static readonly int pageIndex = 1; private static readonly int pageSize = 30; private static readonly int skipCount = (pageIndex - 1) * pageSize; public List<Info> GetInfoList() { int pageIndex = 1; int pageSize = 30; int skipCount = (pageIndex - 1) * pageSize; var infoList = new List<Info>(); using (PartTimeDataContext db = new PartTimeDataContext()) { var query = db.Info .OrderBy(m => m.ID) .Skip(skipCount) .Take(pageSize) .ToList(); infoList = query as List<Info>; } return infoList; }
Linq To SQL生成sql语句如下:
4. row_num() over()...
with infos as ( select r.*, row_number()over(order by r.id desc) as r from [Info] r ) select * from infos where r between 1 and 30;
使用聚合函数和not in分页语句请看http://www.cnblogs.com/paulhe/p/3499920.html。
5. MySQL分页
select * from info where id limit 0,20
比较一下各分页的性能
使用聚合函数或not in来实现分页都不是最好的选择,所以在这比较一下offset ... fetch与row_num() over():
之前用惯了row_num() over(),现在从语法或性能上看来offset...fetch也是不错的选择。