【问题标题】:Compare and synchronize DataTables比较和同步数据表
【发布时间】:2016-01-15 12:08:33
【问题描述】:

我需要比较两个数据表。
dataTable A 包含客户端计算机上的当前数据集。
dataTable B 包含未来对 dataTable A 的更新。

dataTable A structure
ID | firstname  | lastName
 1 | "test"     | "last"
 2 | "whatever" | "someone"
 3 | "hi"       | "hello

dataTable B Structure
ID | firstname  | lastName
 1 | "updated"  | "yes"
 2 ->deleted
 3 | "hi"       | hello" ->unchanged
 4 | "new"      |record " ->row added

当我去 dataTableA.merge(datatableB)

我基本上只是得到 dataTableA 和 dataTableB 添加的行 比如

ID | firstname  | lastName
 1 | "test"     | "last"
 2 | "whatever" | "someone"
 3 | "hi"       | "hello
 1 | "updated"  | "yes"
 3 | "hi"       | hello" ->unchanged
 4 | "new"      |record " ->row added

它在 ID 上不匹配并被更新或删除。我只想比较两个表,更新应该看起来与表 B 完全相同的表 A。我不太确定如何正确完成此操作。

基本上,客户端机器中有一个 SQL 表需要完成更新并准确同步到正在传入的数据表 B。理论上我只想获取表 B 并基本上更新表 A。所以在我需要更新 SQL 表。我尝试过这样的事情。

Dim adapter = New SqlDataAdapter("select * from test_table2", connection)
Using (New SqlCommandBuilder(adapter))
    adapter.Fill(dTable)
    connection.Open()
    adapter.Update(dTable)
End Using

好像没用。

【问题讨论】:

  • @haraman 您编辑的最后一行没有意义。
  • 感谢您的指出,刚刚验证了编辑,想知道那行是从哪里来的,因为当我开始编辑时它已经在那里了。已更正。
  • @Sirus 两个独立的数据表,不能这样直接合并。你可以在这里找到关于数据表的很好的参考A-Practical-Guide-to-NET-DataTables-DataSets
  • 好的...我只是想找到一种方法来同步两个数据表。它们来自不同的数据库,但具有相同的架构。我想分析更新/编辑/删除需要不同的地方,然后更新 sql 表。似乎这很难找到一个简单的方法
  • @Sirus 这两个数据库是否在同一个 SQL Server 实例中?然后,您可以轻松地在 SQL 中完成所有操作。如果数据库可以相互连接,那么您仍然可以在 SQL 中进行操作:What is the T-SQL syntax to connect to another SQL Server?

标签: vb.net datatable merge synchronization compare


【解决方案1】:

如果数据表应该最终相同,而不是使用

dataTableA.merge(datatableB)

试试

dataTableA=datatableB.Copy

从这里获取此信息 https://msdn.microsoft.com/en-us/library/system.data.datatable.copy(v=vs.110).aspx

【讨论】:

    【解决方案2】:

    您的两个数据表是分开创建的,彼此独立。在这种情况下,您可以使用以下 DataTable 和 LINQ 操作,例如

    • Intersect 在两个数据表中查找匹配的行,
    • Except 仅在一个表中查找唯一行
    • ImportRow 将一个 DataTable 的特定行复制到另一个。
    • Copy 将整个数据表复制到另一个中

    可能是这样的

    Dim dtA As DataTable 'Your original Table A
    Dim dtB As DataTable 'Your modified Table B
    Dim dtC As DataTable 'Unchanged Rows
    Dim dtD As DataTable 'Final synchronized Table
    Dim dtE As DataTable 'Deleted Rows
    
    'Populate your Table A and Table B into dtA and dtB
    
    'get unchanged rows into dtC (all rows - changed - deleted)
    dtC = dtA.AsEnumerable.Intersect(dtB.AsEnumerable, DataRowComparer.Default).CopyToDataTable
    
    'Copy all unchanged rows to final table
    dtD = dtC.Copy
    
    'Copy the structure to blank datatable
    dtE = dtC.Clone
    
    'process modified rows (changed + deleted) i.e. (all rows - unchanged rows)
    For Each cdRow As DataRow In dtA.AsEnumerable.Except(dtC.AsEnumerable, DataRowComparer.Default).CopyToDataTable.Rows
        'check if this row exists in modified rows
        If dtB.Select("cid = " & cdRow.Item("cid").ToString).Count > 0 Then
            'This is a modified row copy it to the final table or process it to database
            dtD.ImportRow(dtB.Select("cid = " & cdRow.Item("cid").ToString).CopyToDataTable.Rows(0))
        Else
            'This is a deleted row copy it to the deleted records table or process it directly to the database
            dtE.ImportRow(cdRow)
        End If
    Next
    'Now dtE contains your deleted rows
    'Finally dtD is your synchronized datatable
    

    假设和其他细节:

    • 所有数据表都应具有相同的表结构
    • 此代码假定 ID 列是唯一的,用于识别新行和旧行。
    • 您仍需处理原始数据库中已删除的行 (dtE)。
    • 可以避免使用 DataTable dtD、dtE,但只是为了简化和更好地理解这些概念。
    • 无需稍后在单独的循环中处理 dtD 和 dtE 中的所有记录,您可以直接将它们更新到数据库中,如上面代码中所述。
    • 如果您正在处理大型 DataTable,可能会出现内存、资源、处理/计时相关问题

    【讨论】:

    • 好的,我试过了。我遇到了异常。 dtC = dtA.AsEnumerable.Intersect(dtB.AsEnumerable).CopyToDataTable 附加信息:源不包含 DataRows。
    • 我还没有实现任何异常处理。你不认为异常消息很清楚Additional information: **The source contains no DataRows**。检查 dtB 是否有从表 B 获取的任何记录
    • 我意识到.. 很清楚.. 但它有数据。我知道这是事实
    • 绝对是空白DataTable错误。在上面的代码中 dtA 和 dtB 不能为空。要处理这种情况,您可以从stackoverflow.com/a/7822056/5104101 获得提示,如var dt = rows.Any() ? rows.CopyToDataTable() : table.Clone();
    • Dim query = From a In dtReturnTable Group Join b In dtz On a.Item(0) Equals b.Item(0) Into g = Group where g.Count = 0 Select a
    猜你喜欢
    • 1970-01-01
    • 2020-11-10
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-01-18
    • 1970-01-01
    相关资源
    最近更新 更多