3

我有一个大型数据集(超过 100,000 条记录),我希望将其加载到 DataGridView 中。执行此操作的存储过程可能需要 10 秒或更长时间才能完成。

到目前为止,我有一个 BackgroundWorker 可以防止 UI 锁定,并实现了一个基本的“请稍候”对话框。

我想做的是以某种方式在 DataGridView 中填充结果,因为它们以某种方式从数据库返回。描述它的最佳方式是 SQL Server Management Studio 是如何做到的——当查询运行时,即使查询仍在执行,行也会立即返回。还有一个按钮可以停止查询并保留已返回的行。

我怎样才能在我自己的代码中做到这一点?

DataGridView 仅用于显示数据行,然后用户单击其中一个执行其他操作。没有任何东西被写回数据库。

4

5 回答 5

4

似乎最好的选择是使用某种分页机制,因此您一次只向用户显示一定数量的数据。这将加快提取数据和加载页面的速度。您可以使用 GridView 的内置分页(我建议在这种方法中使用 .NET 缓存,因为它每次都会提取整个数据集,即使它只显示一页记录)。您还可以使用 LINQ to SQL 实现分页,一次只能抓取一个页面。下面是我最近发现的一篇好文章的链接,它解释了如何做到这一点。

http://www.dbtutorials.com/display/linq-to-sql-paging-cs.aspx

于 2008-11-10T22:27:09.427 回答
4

数据网格视图中有 100,000 行?拒绝吧”!

  1. 用户一次看不到 100,000 行
  2. 传输 100,000 行的网络流量并非微不足道
  3. 100,000 个 datagridview 行的内存开销并非微不足道
  4. 用户只需要选择一行并继续
  5. 如果这个应用程序一次被多个用户使用,DBA 会追捕你

听从奥斯汀的建议,一次只显示一页

于 2008-11-11T03:09:50.417 回答
2

正如其他人所建议的那样,在网格中显示 100K 记录听起来是个坏主意,但如果你真的必须......

您的 backgroundworker 线程走在正确的轨道上,但您必须使用数据读取器并在返回行时按顺序读取它们。然后,您的后台工作线程需要为从数据读取器读取的每一行编组一个网格行添加到 UI 线程。

请注意,使用单独的线程来保持 UI 响应的任何好处都将被否定,因为无论如何它都会忙于不断地添加行。我建议您实现某种批处理方法,并让 UI 每秒左右添加一次新行。您需要在这里非常小心,并牢记可能的竞争条件。可能会出现一种情况,您的后台工作人员正在将数据读取器中的行添加到某种集合中,而您的 UI 可能希望同时读取该集合 - 这几乎肯定会导致问题。

于 2008-11-11T07:17:46.547 回答
0

我怀疑您是否可以像 Management Studio 一样在 DataGridView 中执行此操作。我想说的是,当存储过程调用完成时,您会立即获得应用程序中的所有行。

于 2008-11-10T22:14:51.697 回答
0

您也可以研究一些后端调整。在这种情况下添加索引已经帮助了我们很多次。尝试在启用“执行计划”选项的情况下从 SQL Server Management Studio 运行存储过程。寻找存储过程可能陷入困境的地方(即高执行百分比)。当您将鼠标悬停在项目上时,您将看到执行详细信息列表。在列表的底部,查看是否正在比较任何字段。这些对于索引候选人来说是无用的赠品。

于 2008-11-10T23:04:05.997 回答