2009-07-31 115 views
12

我正在写一个wpf destop应用程序,并希望将SQL Server CE用作后端。我试图想出一个有效的数据分页的好方法。在SQL Server Express中,我可以这样做:SQL Server CE中的数据分页(精简版)

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

+0

尼尔,看到我对我的答案的评论。 – 2009-08-08 22:46:21

回答

2

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

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

+0

SqlCeResultSet是否一次从数据库中撤回结果集中的所有内容(如断开连接的DataSet),还是只是打开与数据库的连接并根据请求读取行? 如果它留下来打开数据库的连接,也许我可以使用SqlCeResultSet和ReadAbsolute相结合的方法跳转到我需要的记录,将它们读入一个列表,然后返回列表,并关闭连接。 – Neil 2009-08-07 13:16:55

+1

@Neil,ResultSet/DataReader需要一个持久连接。对于所有意图和目的,它们几乎都只是一个SQL游标。特别好的是,你也可以打开整个表格作为TableDirect,给它一个索引,然后在那个索引上查找,它的* so *很快。 – 2009-08-08 22:45:24

5

我目前也在使用SQL Server CE作为持久性机制的WPF应用程序。我们有几张(40+)桌子,其中一些桌子非常大(5万条记录,至少对我的标准来说这很重要)。

关于直接在SQL CE中进行数据分页的建议是这样的:如果可以的话,就避免它!我使用了Bob King所描述的方法,至少对我而言,它导致了非常丑陋的代码,这是一个真正的维护噩梦。

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

我的用户的一般观点是,如果这会导致后续更快的分页,可以等待一段时间才能显示第一个结果。使用LINQ,分页就像调用Skip和Take方法一样简单。我已经在寻呼机内部实现了这个逻辑,使它非常干燥和美观。

1

有几种方法,但最简单的方法是这样的:

假设

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

然后

  1. 第一个TOP = Pa geSize(10)
  2. 第二顶=每页*页(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
1

我做IMPL使用SQL CE对数据网格进行自定义分页。我实现了在select语句中使用top并在上面的答案中讨论的使用子查询跳过记录的方法。但是对于少量数据来说,它效果很好。随着记录数量的增长,上述方法变得不太有用,并且性能变慢。

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

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

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

我初始化这些变量网格绑定的每一页后。

如果用户点击下一步按钮我从数据库获取顶部(Pagsize)记录大于lastRecord 如果用户点击上一个按钮,我从数据库中获取顶部(PageSize)记录少于firstRecord。在这种情况下,我也通过Id desc订购。在绑定到datagrid之前,使用dataview将datatable重新排序为asc。

它使我的分页效率最高。虽然我不得不花费额外的努力插入和删除记录案例。但我能够解决这个问题。

相关问题