从一个DataTable中选择行而不在另一个DataTable中

时间:2012-01-17 23:06:17

标签: c# linq datatable filtering

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

我正在使用以下LinQ查询

DataTableB

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

当我正在调试时,似乎快速跳过这条线但是当我调用与该查询相关的任何内容时,例如//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>();,似乎需要很长时间,所以我只是停下来该计划。

那么,我做错了什么?

3 个答案:

答案 0 :(得分:3)

预计会减速:在您枚举结果之前不会对查询进行评估,因此您可以非常快速地在调试器中跳过此行:它只是准备查询数据源;查询是在枚举结果时完成的。

据我所知,如果不分析您的代码,问题可能与您将dtProductsdtImport转换为IEnumerable时发生的大量数据库外选择有关:实际上,在进行选择之前,您将两个表中的数据都带入内存。如果你的桌子有相当大的尺寸,这可能是大多数时间的地方。但同样,唯一确定的方法是分析。

答案 1 :(得分: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();

答案 2 :(得分:1)

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

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