从一个DataTable中选择行,而不是从另一个DataTable中选择行

本文关键字:选择 DataTable 另一个 一个 | 更新日期: 2023-09-27 18:20:40

我正在尝试获取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();)时,似乎需要很长时间,所以我只是停止程序。

那么,我做错了什么?

从一个DataTable中选择行,而不是从另一个DataTable中选择行

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

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

速度会减慢:在枚举结果之前,查询不会得到评估,因此您可以很快跳过调试器中的这一行:它所做的只是准备查询数据源;查询是在枚举结果时完成的。

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

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

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