You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.05.25 06:26:30