【问题标题】:Efficiently check if any cell in a DataTable contains a substring有效检查 DataTable 中的任何单元格是否包含子字符串
【发布时间】:2019-04-01 17:16:55
【问题描述】:

我正在使用下面的代码允许用户通过搜索可能位于任何列或任何行中的特定字符串来过滤DataTable。代码需要删除值不存在的行,因为在操作后导出了DataTable

此代码的问题有两个:1) 对于较大的表来说它非常慢,2) 它只能找到一个单元格的完整内容(即,如果“名称”列有一行的值是“Andrew”,用户应该能够搜索“drew”或“and”并获得该结果;现在如果他们搜索“Andrew”,它将返回该行)。

if(!String.IsNullOrEmpty(combo1Text) || !String.IsNullOrEmpty(combo2Text)
                && !String.IsNullOrEmpty(search1Text) && !search1Text.Contains("Type your search for" + comboText + "here"))
            {
                for (int i = tab1table.Rows.Count - 1; i >= 0; i--)
                {
                    DataRow dr = tab1table.Rows[i];
                    if (!dr.ItemArray.Contains(search1Text))
                    {
                        dr.Delete();
                        tab1table.AcceptChanges();
                    }
                    percentprogress++;
                    worker.ReportProgress(percentprogress);
                }
            }

进行我想要的过滤的最佳方法是什么(并且有效地进行,以便它不仅仅是循环遍历所有内容)?

【问题讨论】:

  • 现在拥有代码的方式效率更高。每次删除时搜索 DGV 都会强制刷新 DGV,这会减慢代码速度。通过 DataTable 进行搜索会更加高效。
  • @Magnetron 我认为这种方法不适用于我的情况。此外,我需要删除未通过过滤器的行,并且需要搜索每一列,而不仅仅是一列。
  • 在处理完所有行后只调用一次tab1table.AcceptChanges。这是一项昂贵的手术。

标签: c# winforms


【解决方案1】:

要搜索单元格内容是否包含搜索到的文本,请尝试以下代码:

for (int i = tab1table.Rows.Count - 1; i >= 0; i--)
{
    DataRow dr = tab1table.Rows[i];
    if (!dr.ItemArray.Any(x=>(x as string).Contains(search1Text)))
    {
        dr.Delete();
    }
    percentprogress++;
    worker.ReportProgress(percentprogress);
}
tab1table.AcceptChanges();

如果您有任何非字符串类型的列,则应将(x as string) 替换为x.ToString()

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2018-04-21
    • 1970-01-01
    • 1970-01-01
    • 2021-10-10
    • 2017-01-20
    • 2012-04-30
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多