【问题标题】:Select rows from one DataTable not in another从一个数据表中选择行而不是另一个数据表
【发布时间】:2012-02-12 17:57:23
【问题描述】:

我正在尝试获取DataTableA 中的行列表,其中Column 1 中的值不在DataTableBColumn1 中。

我正在使用以下 LinQ 查询

//Not in Database
var query = from i in dtImport.AsEnumerable()
            where !dtProducts.AsEnumerable().Any(p => p[colP] == i[colI])
            select i;

这样我想要导入表中尚未在产品表中的产品列表。

当我在调试时,这似乎很快跳过了这条线,但是当我调用与该查询相关的任何内容时,例如 int rows = query.Count<DataRow>();DataTable dtResult = query.CopyToDataTable();,它似乎需要很长时间,所以我只是停止了程序。

那么,我做错了什么?

【问题讨论】:

  • 在 linq 编译的查询上进行谷歌搜索

标签: c# linq datatable filtering


【解决方案1】:

您的查询很慢,因为它必须为 dtImport 中的每条记录枚举产品。先将产品放入字典,加快查询速度。

var prod = dtProducts.AsEnumerable().ToDictionary(p => p[colP]);  
var query = from imp in dtImport.AsEnumerable()  
            where !prod.ContainsKey(imp[colI])  
            select imp;  

【讨论】:

    【解决方案2】:

    Linq 使用延迟执行。查询在使用时执行(不是在声明时)
    为了获得更好的性能,您可以使用HashSet,如下所示;

    var set = new HashSet<int>(dtProducts.AsEnumerable().Select(p => p.colP));
    var result = dtImport.AsEnumerable().Where(i => !set.Contains(i[colI])).ToList();
    

    【讨论】:

    • 哇!瞬间奏效!尽管如果我在将其标记为答案之前没有对其进行测试,这对其他人是不公平的:)
    【解决方案3】:

    预计会放缓:在您枚举结果之前不会对查询进行评估,因此您在调试器中很快就跳过了这一行:它所做的只是准备查询数据源;查询是在枚举结果时完成的。

    据我所知,如果不分析您的代码,该问题可能与将 dtProductsdtImport 转换为 IEnumerable 时发生的大型数据库外选择有关:本质上,您带来了在进行选择之前,将两个表中的数据放入内存。如果您的桌子很大,这可能是大部分时间的去处。但同样,唯一确定的判断方法是分析。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2013-01-06
      • 2014-01-01
      • 1970-01-01
      • 2011-11-27
      • 1970-01-01
      • 2021-12-30
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多