如何比较两个DataTable并仅使用不匹配的数据返回记录

时间:2013-10-24 18:34:53

标签: c# linq datatable

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

例如:

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

我想使用货币将Table1A的每个行数据与TableB的行数据进行比较,并仅显示具有不匹配数据的行(U pto列Rate4) enter image description here

感谢您的帮助

3 个答案:

答案 0 :(得分: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();

答案 1 :(得分:0)

或许这样的事情:

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"),
            ...
        };

答案 2 :(得分:0)

试试这个:

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