从一个DataTable中选择行,而不是从另一个DataTable中选择行
本文关键字:选择 DataTable 另一个 一个 | 更新日期: 2023-09-27 18:20:40
我正在尝试获取DataTableA
中的行列表,其中Column 1
中的值不在DataTableB
的Column1
中。
我正在使用以下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使用延迟执行。查询在使用时执行(而不是在声明时执行)
为了获得更好的性能,您可以使用HashSet
,如下所示;
var set = new HashSet<int>(dtProducts.AsEnumerable().Select(p => p.colP));
var result = dtImport.AsEnumerable().Where(i => !set.Contains(i[colI])).ToList();
速度会减慢:在枚举结果之前,查询不会得到评估,因此您可以很快跳过调试器中的这一行:它所做的只是准备查询数据源;查询是在枚举结果时完成的。
据我所知,在不分析代码的情况下,这个问题可能与将dtProducts
和dtImport
转换为IEnumerable
时发生的数据库外大选择有关:本质上,在进行选择之前,您将两个表中的数据带入内存。如果你的桌子很大,这可能是大部分时间的地方。但同样,唯一确定的方法是分析。
您的查询速度很慢,因为它必须为dtImport中的每个记录枚举产品。首先将产品放入字典中,以加快查询速度。
var prod = dtProducts.AsEnumerable().ToDictionary(p => p[colP]);
var query = from imp in dtImport.AsEnumerable()
where !prod.ContainsKey(imp[colI])
select imp;