12

我正在编写一个 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 行,而不必拉回所有数据然后将其过滤以显示给用户,因为这要慢得多。谢谢。

4

5 回答 5

8

如果有人到达此页面寻找答案......我遇到了这篇文章:支持 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

希望这可以帮助

于 2011-01-26T19:41:28.490 回答
5

我目前也在开发一个使用 SQL Server CE 作为持久性机制的 WPF 应用程序。我们有几个(40 多个)表,其中一些非常大(50k 记录,至少对于我的标准来说这很大)。

我对直接在 SQL CE 中进行数据分页的建议是:尽可能避免使用它!我使用了 Bob King 描述的方法,至少对我来说,它导致了非常丑陋的代码,一个真正的维护噩梦。

除非您需要对数万条记录进行分页,否则我认为最好的方法是使用SqlCeDataReader将它们全部加载到自定义类的集合中,然后在内存中对集合进行分页。我发现这种方法比每次都重新执行 SQL 查询响应速度更快,即使使用缓存也是如此。发生的情况是,在我的情况下,查询相当复杂,而 SqlCeDataReader 的性能足够好,以至于几乎察觉不到性能损失。无需指出,在第一批加载之后,每个页面更改几乎都是瞬间发生的,因为所有内容都保存在内存中。

我的用户的普遍看法是,如果稍后会导致更快的分页,则可以等待更长的时间等待第一个结果出现。使用 LINQ,分页就像调用 Skip 和 Take 方法一样简单。我已经在 Pager<T> 类中实现了这个逻辑,使它非常干燥和漂亮。

于 2009-11-04T03:35:30.360 回答
2

老实说,最快的方法可能是使用SqlCeDataReader并调用 .Read() 10 次。然后当用户移动到下一页时,您已经指向第 11 个结果,并且可以再阅读 10 个。如果您需要倒退,您可以缓存您的结果或切换到支持seek的SqlCeResultSet

此外,根据经验,SqlCeDataReader/Result 是与桌面上的数据库交互的绝对最快的方式。它可以比使用 DataSets/DataAdapters 快 100 倍。

于 2009-08-06T15:12:14.580 回答
1

有几种方法,但最简单的方法如下:

假设

  1. 页面大小 = 10
  2. 页 = 2

然后

  1. 第一个 TOP = PageSize (10)
  2. 第二个 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
于 2010-10-23T02:05:36.977 回答
1

我确实使用 SQL CE 为数据网格实现了自定义分页。如上面的答案所述,我实现了在 select 语句中使用 top 并使用子查询跳过记录的方法。但它适用于少量数据。随着记录数以千计的增长,上述方法变得不那么有用并且性能变得缓慢。

我使用自己的技术解决了性能不佳的问题。我所做的是将每个页面上第一条和最后一条记录的 id 存储在变量中。

dim firstRecord=dt.rows(0)("id")

dim lastRecord=dt.Rows(dt.rows.count-1)("id")

在为每个页面绑定网格后,我初始化这些变量。

如果用户单击下一个按钮,我从数据库中获取大于 lastRecord 的顶部(Pagsize)记录如果用户单击上一个按钮,我从数据库中获取少于 firstRecord 的顶部(PageSize)记录。在这种情况下,我也按 Id desc 订购。并在绑定到数据网格之前使用数据视图重新排序数据表以升序。

它使我的寻呼效率最高。虽然我不得不为插入和删除记录案例付出一些额外的努力。但我能够处理。

于 2011-04-13T13:07:14.660 回答