SQL Server CE(精简版)中的数据分页
Posted
技术标签:
【中文标题】SQL Server CE(精简版)中的数据分页【英文标题】:Data paging in SQL Server CE (Compact Edition) 【发布时间】:2009-07-31 15:20:19 【问题描述】:我正在编写一个 wpf destop 应用程序,并希望使用 SQL Server CE 作为后端。我正在尝试想出一种进行有效数据分页的好方法。在 SQL Server Express 中,我可以这样做:
Select ID, FirstName, LastName
From (SELECT ROW_NUMBER() OVER (ORDER BY ID)
AS Row, ID, FirstName, LastName
From TestTable
)
WHERE Row > 1 AND Row <= 10
在 SQL Server CE 中有什么可比的吗?我不完全确定什么是支持和不支持。我只想从数据库中一次返回 10 行,而不必拉回所有数据然后将其过滤以显示给用户,因为这要慢得多。谢谢。
【问题讨论】:
尼尔,看看我对我的回答的评论。 【参考方案1】:如果有人到达此页面寻找答案... 我遇到了这篇文章:支持 SQL Server CE 4.0 中的分页查询
http://beyondrelational.com/blogs/jacob/archive/2010/07/13/support-for-paging-queries-in-sql-server-ce-4-0.aspx
希望对你有帮助
【讨论】:
感谢 lailalta,在我最初发布此问题时,SQL Server CE 4.0 尚不可用,但我认为这绝对是未来处理分页的方法。【参考方案2】:我目前还在开发一个使用 SQL Server CE 作为持久性机制的 WPF 应用程序。我们有几个(40 多个)表,其中一些非常大(5 万条记录,至少对于我的标准来说这很大)。
我对直接在 SQL CE 中进行数据分页的建议是:尽可能避免使用它!我使用了 Bob King 描述的方法,至少对我来说,它导致了非常丑陋的代码,一个真正的维护噩梦。
除非您需要对数万条记录进行分页,否则我认为最好的方法是使用SqlCeDataReader 将它们全部加载到自定义类的集合中,然后在内存中对集合进行分页。我发现这种方法比每次都重新执行 SQL 查询响应速度更快,即使使用缓存也是如此。发生的情况是,在我的情况下,查询相当复杂,而 SqlCeDataReader 的性能足够好,以至于几乎察觉不到性能损失。无需指出,在第一批加载后,每次页面更改几乎都是瞬间发生的,因为所有内容都保存在内存中。
我的用户的普遍意见是,如果稍后会导致更快的分页,则可以等待一段时间以显示第一个结果。使用 LINQ,分页就像调用 Skip 和 Take 方法一样简单。我在 Pager
【讨论】:
【参考方案3】:老实说,最快的方法可能是使用 SqlCeDataReader 并调用 .Read() 10 次。然后当用户移动到下一页时,您已经指向第 11 个结果,并且可以再阅读 10 个。如果您需要倒退,您可以缓存结果或切换到支持seeking 的SqlCeResultSet。
此外,根据经验,SqlCeDataReader/Result 绝对是与桌面上的数据库交互的最快方式。它可以比使用 DataSets/DataAdapters 快 100 倍。
【讨论】:
SqlCeResultSet 是一次从数据库中拉回结果集中的所有内容(如断开连接的 DataSet),还是只是打开与数据库的连接并根据请求读取行?如果它使与数据库的连接保持打开状态,也许我可以结合使用 SqlCeResultSet 和 ReadAbsolute 方法来跳转到我需要的记录,将它们读入列表,然后返回列表并关闭连接。 @Neil,ResultSet/DataReader 需要持久连接。出于所有意图和目的,它们几乎只是一个 SQL 游标。特别棒的是,您还可以将整个表格作为 TableDirect 打开,给它一个索引,然后在该索引上查找,它非常快。【参考方案4】:有几种方法,但最简单的方法如下:
假设
-
页面大小 = 10
页面 = 2
然后
-
第一个 TOP = PageSize (10)
第二个 TOP = PageSize * Page (20)
SELECT
[Page].[ID],
[Page].[FirstName],
[Page].[LastName]
FROM
(
SELECT TOP (10)
[FirstRows].[ID],
[FirstRows].[FirstName],
[FirstRows].[LastName]
FROM
(
SELECT TOP (20)
[TestTable].[ID],
[TestTable].[FirstName],
[TestTable].[LastName]
FROM
[TestTable]
ORDER BY
[TestTable].[ID] ASC
) AS [FirstRows]
ORDER BY
[FirstRows].[ID] DESC
) AS [Page]
ORDER BY
[Page].[ID] ASC
【讨论】:
【参考方案5】:我确实使用 SQL CE 为数据网格实现了自定义分页。如上面的答案所述,我实现了在 select 语句中使用 top 并使用子查询跳过记录的方法。但它适用于少量数据。随着记录数以千计的增长,上述方法变得不那么有用并且性能变得缓慢。
我使用自己的技术解决了性能不佳的问题。我所做的是将每个页面上第一条和最后一条记录的 id 存储在变量中。
dim firstRecord=dt.rows(0)("id")
和
dim lastRecord=dt.Rows(dt.rows.count-1)("id")
我在为每个页面绑定网格后初始化这些变量。
如果用户单击下一步按钮,我会从数据库中获取大于 lastRecord 的 top(Pagsize) 记录 如果用户单击上一个按钮,我从数据库中获取的 top(PageSize) 记录少于 firstRecord。在这种情况下,我也按 Id desc 订购。并在绑定到数据网格之前使用数据视图对数据表重新排序以升序。
它使我的寻呼效率最高。虽然我不得不为插入和删除记录案例付出一些额外的努力。但我能应付。
【讨论】:
以上是关于SQL Server CE(精简版)中的数据分页的主要内容,如果未能解决你的问题,请参考以下文章
如何在 vs2010 中创建/添加 sql server 精简版数据库?
使用 SQLConnection 连接到 SQL CE 数据库