我在C#Windows应用程序中有SqlDataAdapter
查询。在DataGridView
填写返回行之前,我需要知道返回行数,因为当数字为 100 万行时,填充方法需要 9 秒。
我需要一种方法,不需要填写数据表中的所有数据并获取计数,然后我使用分页原理来显示这样的数据
DataTable dt = new DataTable();
query = new Classes.order().GetAllBills();
query.Fill(dt);
DateTime date1 = System.DateTime.Now;
MaxCount = dt.Rows.Count;
int maxPag = (MaxCount / 25)+1;
lblMaxCount.Text = MaxCount.ToString() ;
lblNumOfPagFromAll.Text = (CounterPaging / 25) + "/" + maxPag;
dt = new DataTable();
query.Fill(CounterPaging,maxRecord,dt);
dataGridView1.DataSource = dt;
>在获取所有行之前,SqlDataAdapter
无法返回行数。这仅仅是因为基础数据库驱动程序不会提供此信息。因此,您必须在获取行时或之后计算行数。
选择计数(*(
或者,您需要按照 Progman 的建议查询数据库以获取结果数。但这有一些缺点。
- 首先,数据库需要获取数据两次。虽然缓存可能会使第二次访问更快,但这也可能不会发生,例如,如果行数非常大并刷新缓存。
- 其次,这是一个竞争条件。
SELECT COUNT(*)
按SqlDataAdapter
返回完全不同的行数后,数据可能会更改。
选择顶部
另一种解决方案是让数据库处理分页。在 T-SQL 中,SELECT TOP n ...
将完成这项工作。
缺点是您无法以这种方式检索总页数。 但是很容易检查是否有进一步的数据。只需选择比页面大小多一行即可。如果你得到 n+1 行,还有另一个页面。
DataTable
= 性能不佳
最后一点:如果性能很重要,请删除数据表和适配器。它们不打算用于明显超过屏幕上容纳的数据。 特别是如果您有许多值类型(如int
或DateTime
,由于过度的自动装箱,效果显着。
前段时间我以这种方式重构了一个 C# 应用程序,速度提高了近两个数量级。 我同时做了另一个更改:我从结果集中的不同行中删除了相同的字符串。这也将内存占用量减少了近一个数量级,因为某些值经常重复。
正是如此之快,我最终将所有数据加载到会话缓存中并从该缓存进行分页。即使是几百万行也只用了一秒钟。