【问题标题】:compare two datatables and get difference rows in C#比较两个数据表并在 C# 中获取差异行
【发布时间】:2015-09-11 06:42:32
【问题描述】:

这是一个例子,假设我有两个数据表。

Table_1
id     name     age
===================
1      john     20
2      henry    25
3      sam      18
4      tom      30


Table_2
id     name     age
===================
1      john     20
2      henry    26     <=== Edited Row
3      sam      19     <=== Edited Row 
4      tom      30

这两个表在不同的数据库中(具有相同的架构)。
我将它们加载到两个 DataTable 中,并使用 Except

dt_Table_1.AsEnumerable().Except(dt_Table_2.AsEnumerable())

使用 Except 仅返回新插入的行,但不返回已编辑的行。
我只想获取已编辑的行。
上面的表格只是例子,我的真实数据有很多行,所以我必须考虑性能。这就是为什么我不想为每一行循环。
有没有更好的办法?

【问题讨论】:

  • Linq 并不神奇。 Except 被实现为:Set&lt;TSource&gt; set = new Set&lt;TSource&gt;(comparer); foreach (TSource element in second) set.Add(element); foreach (TSource element in first) if (set.Add(element)) yield return element; - 所以你会得到 n*m 循环。
  • Enumerable.Except 具有指定比较器 msdn.microsoft.com/en-us/library/vstudio/… 的静态重载,您可以根据需要定义它。但是,您的 LINQ 的紧凑性消失了 :-(

标签: c# datatable compare


【解决方案1】:

您可以从数据表中获取更改的行并将它们添加到您的结果中。

DataTable changedRecordsTable = dataTable1.GetChanges();//get changed rows

dt_Table_1.AsEnumerable().Except(dt_Table_2.AsEnumerable()).Union(changedRecordsTable.AsEnumerable())

您应该在调用接受更改之前执行此操作,并记住,这会比较两个不同实例的不同值的哈希值,因此结果将包含所有数据表中的所有行(即不删除重复项)

【讨论】:

    【解决方案2】:

    您可以简单地构造一个查询,该查询将为您提供更改的行:

    select * from table_1 inner join table_2 on table_1.id=table_2.id and table_1.age<>table_2.age
    

    但是如果你添加或删除行,它们不会出现,你可以运行

    select * from table_1 where id not in (select id from table_2)
    

    要从 table_1 中删除所有这些并

    select * from table_2 where id not in (select id from table_1)
    

    获取从 table_2 中删除的行

    您可以将它们全部组合到一个查询中,并通过运行以下命令设置状态(已删除或已编辑):

    select table_1.id, table_1.name, table_1.age, 'edited' as rowstatus from table_1 inner join table_2 on table_1.id=table_2.id and table_1.age<>table_2.age
    union
    select id, name, age, 'deleted table_1' as rowstatus from table_1 where id not in (select id from table_2)
    union
    select id, name, age, 'deleted from table_2' as rowstatus from table_2 where id not in (select id from table_1)
    

    【讨论】:

    • 如果name列也可以改变,需要添加到sql中:select * from table_1 inner join table_2 on table_1.id=table_2.id and (table_1.agetable_2.age或 table_1.nametable_2.name)
    • 如果您尝试比较,但无法使用 id 连接两个表怎么办?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2023-03-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-09-18
    • 2022-06-28
    • 2013-04-27
    相关资源
    最近更新 更多