【问题标题】:How to compare two DataTables and returns records with only the unmatching data如何比较两个 DataTables 并返回仅包含不匹配数据的记录
【发布时间】:2013-10-24 18:34:53
【问题描述】:

我正在尝试比较两个 DataTables TableA 和 TableB。

例如:

TableA 有 7 列和 5 行。货币列是主键 表 B 5 列 3 行。货币列为主键

我想使用货币将 Table1A 的每行数据与 TableB 的行数据进行比较,并仅显示数据不匹配的行(至 Rate4 列)

感谢您的帮助

【问题讨论】:

  • 到目前为止你尝试了什么?
  • @Siva,我正在尝试遍历 TableA 并获取货币代码。使用货币,从 TableB 中检索相应的记录并比较数据。这可行,但代码看起来很糟糕。我的意思是在真实表中,总数列接近 20
  • 发布你的代码
  • @我想使用 Linq 代替我现在使用的 foreach 循环。您还想要 DataTable Foreach 代码吗?感谢您的帮助

标签: c# linq datatable


【解决方案1】:
var tableA = new DataTable();
tableA.Columns.Add("Currency", typeof(string));
tableA.Columns.Add("Rate1", typeof(decimal));
tableA.Columns.Add("Rate2", typeof(decimal));
tableA.Columns.Add("Rate3", typeof(decimal));
tableA.Columns.Add("Rate4", typeof(decimal));
tableA.Columns.Add("Rate5", typeof(decimal));
tableA.Columns.Add("Rate6", typeof(decimal));

tableA.Rows.Add("USD", 1m, 2m, 3m, 4m, 5.5m, 4.5m);
tableA.Rows.Add("JPY", 1.11m, 4.1m, 3.3m, 4.6m, 5.5m, 3.3m);
tableA.Rows.Add("GBP", 3.0m, 1m, 3m, 4m, 7.7m, 8.8m);
tableA.Rows.Add("EUR", 3.0m, 1m, 3m, 4m, 7.7m, 8.8m);
tableA.Rows.Add("MXN", 3.0m, 1m, 3m, 4m, 7.7m, 8.8m);


var tableB = new DataTable();
tableB.Columns.Add("Currency", typeof(string));
tableB.Columns.Add("Rate1", typeof(decimal));
tableB.Columns.Add("Rate2", typeof(decimal));
tableB.Columns.Add("Rate3", typeof(decimal));
tableB.Columns.Add("Rate4", typeof(decimal));

tableB.Rows.Add("USD", 1m, 2m, 3m, 4m);
tableB.Rows.Add("JPY", 1.11m, 9.9m, 3.3m, 4.6m);
tableB.Rows.Add("GBP", 3m, 1m, 3m, 4m);

var query = from r1 in tableA.AsEnumerable()
            from r2 in tableB.AsEnumerable()
            where
                r1.Field<string>("Currency") == r2.Field<string>("Currency")

            && r1.Field<decimal>("Rate1") == r2.Field<decimal>("Rate1")
            && r1.Field<decimal>("Rate2") == r2.Field<decimal>("Rate2")
            && r1.Field<decimal>("Rate3") == r2.Field<decimal>("Rate3")
            && r1.Field<decimal>("Rate4") == r2.Field<decimal>("Rate4")
    select r2;

var result = tableB.AsEnumerable().Except(query).ToList();

【讨论】:

    【解决方案2】:

    可能是这样的:

    var q = from a in dtA.AsEnumerable()
            join b in dtB.AsEnumerable()
              on a.Field<string>("Currency") equals b.Field<string>("Currency")
    
            where a.Field<double>("Rate1") != b.Field<double>("Rate1") || 
                  a.Field<double>("Rate2") != b.Field<double>("Rate2") || ....
    
            select new 
            {
                Currency = a.Field<string>("Currency"),
                Rate1    = a.Field<double>("Rate1") == b.Field<double>("Rate1") ? 
                               0 : a.Field<double>("Rate1"),
                Rate2    = a.Field<double>("Rate2") == b.Field<double>("Rate2") ? 
                               0 : a.Field<double>("Rate2"),
                ...
            };
    

    【讨论】:

    • 感谢 Magnus,我会测试您的解决方案并尽快发布结果。
    【解决方案3】:

    试试这个:

    DataTable dt = TableB.Clone();
    dt = TableA.AsEnumerable().Join(TableB.AsEnumerable(),
                                    row=>row.Field<string>(0),
                                    row=>row.Field<string>(0), (a,b)=> new {a,b})
            .Select(pair=> {
              DataRow row = dt.NewRow();
              row.SetField<string>(0, pair.a.Field<string>(0));
              bool notNull = false;
              for(int i = 1; i < 5; i++){ 
                var a = pair.a.Field<decimal>(i);
                var b = pair.b.Field<decimal>(i);
                if(a == b) row.SetField<decimal>(i, 0);
                else {
                   row.SetField<decimal>(i, Math.Max(a,b));
                   notNull = true;
                }
              }
              return notNull ? row : null;
           }).Where(row=>row != null).CopyToDataTable();
    

    注意:我假设Rate X所有列中的数据类型是decimal,第一列Currency当然是string

    【讨论】:

      猜你喜欢
      • 2022-01-24
      • 1970-01-01
      • 2021-03-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-10-14
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多