代码之家  ›  专栏  ›  技术社区  ›  LogicalDesk

比较两个相同数据表中每行的更改值c#

c#
  •  0
  • LogicalDesk  · 技术社区  · 7 年前

    我需要比较两个具有相同模式的子表达式,并将差异移动到另一个模式中。下面是我的代码,它不能正常工作:

    DataTable dt1 = new DataTable("TableChanged");
    dt1.Columns.Add("StateID",typeof(int));
    dt1.Columns.Add("StateInitial");
    dt1.Columns.Add("IsActive");
    
    dt1.Rows.Add(new object[] { 10, "GA", 1 });
    dt1.Rows.Add(new object[] { 11, "HI", 0 });
    dt1.Rows.Add(new object[] { 12, "ID", 1 });
    dt1.Rows.Add(new object[] { 13, "IL", 1 });
    dt1.Rows.Add(new object[] { 14, "IN", 0 });
    dt1.Rows.Add(new object[] { 15, "IA", 1 });
    dt1.Rows.Add(new object[] { 23, "MN", 0 });
    
    DataTable dt2 = new DataTable("TableOriginal");
    dt2.Columns.Add("StateID", typeof(int));
    dt2.Columns.Add("StateInitial");
    dt2.Columns.Add("IsActive");
    
    dt2.Rows.Add(new object[] { 10, "GA", 1 });
    dt2.Rows.Add(new object[] { 11, "HI", 1 });
    dt2.Rows.Add(new object[] { 12, "ID", 1 });
    dt2.Rows.Add(new object[] { 13, "IL", 0 });
    dt2.Rows.Add(new object[] { 14, "IN", 1 });
    dt2.Rows.Add(new object[] { 15, "IA", 1 });
    dt2.Rows.Add(new object[] { 23, "MN", 1 });
    var matched = from table1 in dt1.AsEnumerable()
                  join table2 in dt2.AsEnumerable() on table1.Field<int>("StateID") equals table2.Field<int>("StateID")
                  //where table1.Field<object>("IsActive") == "0"
                  where table1.Field<string>("StateInitial") == table2.Field<string>("StateInitial") || table1.Field<object>("IsActive") == table2.Field<object>("IsActive") 
                  select table1;
    var missing = from table1 in dt1.AsEnumerable()
                  where !matched.Contains(table1)
                  select table1;
    

    经过比较,我想得到如下结果:

      StateID|StateInitial|IsActive
        11         "HI"         0
        13         "IL"         1
        14         "IN"         0
        23         "MN"         0 
    
    1 回复  |  直到 7 年前
        1
  •  1
  •   Tim Schmelter    7 年前

    你可以使用 DataRowComparer.Default ,它比较 DataRow ,对于linq方法 Intersect Except 。后者给你遗漏的行,你想要的结果:

    DataRowComparer<DataRow> fieldComparer = DataRowComparer.Default;
    IEnumerable<DataRow> matched = dt1.AsEnumerable().Intersect(dt2.AsEnumerable(), fieldComparer);
    IEnumerable<DataRow> missing = dt1.AsEnumerable().Except(dt2.AsEnumerable(), fieldComparer);
    

    如果要将丢失的行添加到第三个表中,可以使用:

    DataTable result = missing.CopyToDataTable();
    

    但我建议使用不同的方法,因为如果没有缺少行,则会引发异常:

    DataTable result = dt1.Clone(); // empty, same schema
    foreach(DataRow row in missing)
        result.ImportRow(row);