uri*_*ini 11 .net sql linq pagination
许多应用程序都有网格,一次一页地显示数据库表中的数据.其中许多还允许用户选择每页的记录数,按任何列排序,并在结果中来回导航.
在不将整个表格带到客户端然后过滤客户端上的数据的情况下,实现此模式的好算法是什么.如何将您想要显示的记录带给用户?
LINQ是否简化了解决方案?
Mic*_*tum 11
在MS SQL Server 2005及更高版本上,ROW_NUMBER()似乎工作:
DECLARE @PageNum AS INT;
DECLARE @PageSize AS INT;
SET @PageNum = 2;
SET @PageSize = 10;
WITH OrdersRN AS
(
SELECT ROW_NUMBER() OVER(ORDER BY OrderDate, OrderID) AS RowNum
,OrderID
,OrderDate
,CustomerID
,EmployeeID
FROM dbo.Orders
)
SELECT *
FROM OrdersRN
WHERE RowNum BETWEEN (@PageNum - 1) * @PageSize + 1
AND @PageNum * @PageSize
ORDER BY OrderDate
,OrderID;
Run Code Online (Sandbox Code Playgroud)
我建议使用LINQ,或尝试复制它的功能.我有一个应用程序,我使用LINQ Take和Skip方法来检索分页数据.代码看起来像这样:
MyDataContext db = new MyDataContext();
var results = db.Products
.Skip((pageNumber - 1) * pageSize)
.Take(pageSize);
Run Code Online (Sandbox Code Playgroud)
运行SQL Server Profiler显示LINQ正在将此查询转换为SQL,类似于:
SELECT [ProductId], [Name], [Cost], and so on...
FROM (
SELECT [ProductId], [Name], [Cost], [ROW_NUMBER]
FROM (
SELECT ROW_NUMBER() OVER (ORDER BY [Name]) AS [ROW_NUMBER],
[ProductId], [Name], [Cost]
FROM [Products]
)
WHERE [ROW_NUMBER] BETWEEN 10 AND 20
)
ORDER BY [ROW_NUMBER]
Run Code Online (Sandbox Code Playgroud)
简单来说:
1.过滤行并使用ROW_NUMBER函数按所需顺序添加行号.
2.过滤(1)以仅返回页面上所需的行号.
3.按行号排序(2),这与您想要的顺序相同(在本例中,按名称).
在数据库中基本上有两种分页方式(我假设你使用的是SQL Server):
其他人已经解释了ROW_NUMBER() OVER()排名功能如何用于执行页面.值得一提的是,SQL Server 2012最终包含对SQL标准OFFSET .. FETCH子句的支持:
SELECT first_name, last_name, score
FROM players
ORDER BY score DESC
OFFSET 40 ROWS FETCH NEXT 10 ROWS ONLY
Run Code Online (Sandbox Code Playgroud)
如果您正在使用SQL Server 2012并且向后兼容性不是问题,那么您应该更喜欢这个子句,因为SQL Server在极端情况下会更好地执行它.
在SQL中执行分页有一种完全不同的,快得多但却鲜为人知的方法.这通常被称为"搜索方法",如本博客文章中所述.
SELECT TOP 10 first_name, last_name, score
FROM players
WHERE (score < @previousScore)
OR (score = @previousScore AND player_id < @previousPlayerId)
ORDER BY score DESC, player_id DESC
Run Code Online (Sandbox Code Playgroud)
该@previousScore和@previousPlayerId值是来自前一页的最后一条记录的相应值.这允许您获取"下一页".如果ORDER BY方向是ASC,只需使用>.
使用上述方法,您无法在未先读取前40条记录的情况下立即跳转到第4页.但通常情况下,你不想跳得那么远.相反,您可以获得更快的查询,该查询可能能够在固定时间内获取数据,具体取决于您的索引.此外,无论基础数据是否发生变化,您的页面都将保持"稳定"状态(例如,在第4页上,当您在第4页时).
例如,这是在Web应用程序中延迟加载更多数据时实现分页的最佳方法.
注意,"搜索方法"也称为键集寻呼.