【发布时间】:2019-10-11 09:00:31
【问题描述】:
我正在编写一个销售程序,为此我需要一个浏览窗口,用户可以在其中浏览他要出售的所有产品。这可能意味着成千上万的产品,因此过滤是唯一的方法。我发现最快的过滤方法是用产品填充 DataTable(而不是直接填充 DataGridView,这是我的第一个解决方案)并使用它的过滤功能。
private void nameTB_TextChanged(object sender, EventArgs e)
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
}
这完成了仅可视化销售人员(从现在开始:用户)正在寻找的内容的工作,并且它完美地适用于大约 300 行(产品)。 将其增加到 10000 种产品(这不仅仅是为了从商店测试其当前数据库)并且加载时间从 1 秒成倍增长到 40 秒,这在销售环境中是不可接受的。
产品在后台的 MySQL 数据库中。查询并将其保存到 DataTable 需要不到一秒钟的时间,这对于 10000 个产品是可以接受的,当我尝试将其可视化时问题就来了。一个简单的:
datagridview1.DataSource = browseDataTable;
大约需要 4 秒,这是可以接受的,但是对于这个应用程序,我需要在我的 6 列 + 标题中添加样式(所有列都有不同的字体,有些换行,有些没有,等等)这增加了加载时间约为 40 秒,但没有样式,在光线充足的房间中质量较低的触摸显示器上,用户将无法看到行。 限制它是要走的路,我没有找到更好的解决方案然后使用这样的东西
browseDataTable.AsEnumerable().Take(100).CopyToDataTable(visibleDataTable, LoadOption.OverwriteChanges);
datagridview1.DataSource = visibleDataTable;
这使得它再次可视化 1 秒。
我的问题是当我尝试将限制与过滤后的产品一起使用时(仅可视化过滤后的前 100 行)。 尝试组合哪个 DataTable 应该是 DataGridView 的 DataSource,例如这个:
browseDataTable.AsEnumerable().Take(100).CopyToDataTable(visibleDataTable, LoadOption.OverwriteChanges); //done once somewhere
private void nameTB_TextChanged(object sender, EventArgs e)
{
if(nameTB.Text == "")
datagridview1.DataSource = visibleDataTable;
else
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
datagridview1.DataSource = browseDataTable;
}
}
没有用,因为通常还有太多产品,最多 3 个字母,每个字母后有 5 秒延迟,3-4 个字母后,它是瞬时的。
理想的解决方案是这样的:
private void nameTB_TextChanged(object sender, EventArgs e)
{
browseDataTable.DefaultView.RowFilter = "name LIKE '%" + nameTB.Text + "%'";
browseDataTable.AsEnumerable().Take(100).CopyToDataTable(visibleDataTable, LoadOption.OverwriteChanges);
}
但这也不起作用,因为 'Take(100)' 总是从 DataTable 中取出前 100 个,无论是否过滤。
(限制查询本身也不起作用,因为这样会在每个字母处都有一个查询,这对于联网的服务器会增加网络拥塞并且速度会很慢,特别是如果用户开始快速书写)
【问题讨论】:
-
如果你得到的值小于这个值,Take 不会报错。所以尝试一个像 10000 这样的数字,它会在 5 秒内返回结果。
-
我的问题不在于 Take 不够,我可以这样做,但是它会和原版一样慢,因为它是原版的精确副本,所以事实上我可以直接使用原版。
-
只有当你的数量少于拍摄数量时才会变慢。
-
所以你要我取10000复制到一个新的DataTable,然后过滤新的DataTable?
-
这是一种方式。您可以使用 RowFilter 中的 Count 属性,这可能更快 Count(*) docs.microsoft.com/en-us/dotnet/api/…
标签: c# filter datagridview datatable limit