在C# LINQ中使用多Where子句进行DataTable数据比较
用C# LINQ多Where子句比较两个DataTable的差异
看起来你需要基于barcode(产品唯一标识)来关联两个DataTable,找出那些在两个表中都存在,但productname或pricesell不一致的记录对吧?下面是具体的实现方案:
前提说明
我假设dtDataForExistingProducts也包含pricesell字段(因为你提到要比较价格差异),如果实际没有的话,可以去掉对应的比较条件。另外,我们用barcode作为关联两个表的唯一匹配键,这比Id更适合跨系统的产品匹配。
实现代码
方式1:找出所有存在差异的记录(名称或价格不同)
// 先关联两个表,基于barcode匹配 var differingProducts = from catalog in dtCatalogFromMySql.AsEnumerable() join existing in dtDataForExistingProducts.AsEnumerable() on catalog.Field<string>("barcode") equals existing.Field<string>("barcode") // 多Where条件:名称不同 或者 价格不同 where catalog.Field<string>("productname") != existing.Field<string>("productname") || catalog.Field<decimal>("pricesell") != existing.Field<decimal>("pricesell") select new { Barcode = catalog.Field<string>("barcode"), MySqlProductName = catalog.Field<string>("productname"), ExistingProductName = existing.Field<string>("productname"), MySqlSellPrice = catalog.Field<decimal>("pricesell"), ExistingSellPrice = existing.Field<decimal>("pricesell"), DifferenceType = catalog.Field<string>("productname") != existing.Field<string>("productname") && catalog.Field<decimal>("pricesell") != existing.Field<decimal>("pricesell") ? "名称和价格都不同" : catalog.Field<string>("productname") != existing.Field<string>("productname") ? "产品名称不同" : "价格不同" }; // 遍历结果查看差异 foreach (var item in differingProducts) { Console.WriteLine($"条码:{item.Barcode} | 差异类型:{item.DifferenceType}"); Console.WriteLine($"MySQL名称:{item.MySqlProductName} | 现有系统名称:{item.ExistingProductName}"); Console.WriteLine($"MySQL价格:{item.MySqlSellPrice} | 现有系统价格:{item.ExistingSellPrice}\n"); }
方式2:按差异类型分别筛选
如果你需要单独获取某一类差异的记录,可以拆分Where条件:
// 仅产品名称不同的记录 var nameDifferences = from catalog in dtCatalogFromMySql.AsEnumerable() join existing in dtDataForExistingProducts.AsEnumerable() on catalog.Field<string>("barcode") equals existing.Field<string>("barcode") where catalog.Field<string>("productname") != existing.Field<string>("productname") && catalog.Field<decimal>("pricesell") == existing.Field<decimal>("pricesell") select new { Barcode = catalog.Field<string>("barcode"), MySqlName = catalog.Field<string>("productname"), ExistingName = existing.Field<string>("productname") }; // 仅价格不同的记录 var priceDifferences = from catalog in dtCatalogFromMySql.AsEnumerable() join existing in dtDataForExistingProducts.AsEnumerable() on catalog.Field<string>("barcode") equals existing.Field<string>("barcode") where catalog.Field<decimal>("pricesell") != existing.Field<decimal>("pricesell") && catalog.Field<string>("productname") == existing.Field<string>("productname") select new { Barcode = catalog.Field<string>("barcode"), MySqlPrice = catalog.Field<decimal>("pricesell"), ExistingPrice = existing.Field<decimal>("pricesell") }; // 名称和价格都不同的记录 var bothDifferences = from catalog in dtCatalogFromMySql.AsEnumerable() join existing in dtDataForExistingProducts.AsEnumerable() on catalog.Field<string>("barcode") equals existing.Field<string>("barcode") where catalog.Field<string>("productname") != existing.Field<string>("productname") && catalog.Field<decimal>("pricesell") != existing.Field<decimal>("pricesell") select new { Barcode = catalog.Field<string>("barcode"), MySqlName = catalog.Field<string>("productname"), ExistingName = existing.Field<string>("productname"), MySqlPrice = catalog.Field<decimal>("pricesell"), ExistingPrice = existing.Field<decimal>("pricesell") };
关键要点
- 必须调用
AsEnumerable()把DataTable转换为可枚举的集合,这样才能使用LINQ查询。 - 使用
Field<T>()方法来安全地获取DataRow中的字段值,注意要匹配正确的数据类型(比如价格用decimal而不是double,避免精度问题)。 - 多Where条件用
&&(逻辑与)和||(逻辑或)组合,根据你的需求灵活调整。 - 如果
dtDataForExistingProducts没有pricesell字段,直接去掉价格相关的比较条件即可。
内容的提问来源于stack exchange,提问作者Mangrio
相关产品推荐
相关产品推荐

