首页 > 解决方案 > 比较两个相同数据表的每一行以获取更改的值 C#

问题描述

我需要比较两个具有相同架构的数据表并将差异移到另一个数据表中。以下是我无法正常工作的代码:

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 

标签: c#

解决方案


您可以使用DataRowComparer.Default比较 a 的每个字段DataRow的 LINQ 方法IntersectExcept. 后者为您提供缺少的行,即您想要的结果:

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);

推荐阅读