在 DataRowState.Modified 中合并两个相同的 DataTables 结果

2024-04-25

我假设如果两个相同的话是错误的吗DataTables are merged每行的状态将被保留?

看一下这个简单的例子。它创建两个相同的表并合并updated表与original桌子。但返回的表在original.GetChanges() is not Nothing正如预期的那样。此外,每行的状态original表更改为Modified.

那么我错过了什么?我真的必须创建自己的合并方法才能实现此目的吗?

Public Sub Test()

    Dim original As DataTable = Me.CreateTableWithData()
    Dim updated As DataTable = Me.CreateTableWithData()
    Dim preserveChanges As Boolean = True
    Dim msAction As MissingSchemaAction = MissingSchemaAction.Ignore

    original.Merge(updated, preserveChanges, msAction)

    Dim changes As DataTable = original.GetChanges()

    MessageBox.Show(String.Format("Count={0}", If((changes Is Nothing), 0, changes.Rows.Count)), Me.Text, MessageBoxButtons.OK, MessageBoxIcon.Information)

    If (Not changes Is Nothing) Then changes.Dispose() : changes = Nothing
    updated.Dispose() : updated = Nothing
    original.Dispose() : original = Nothing

End Sub

Private Function CreateTableWithData() As DataTable
    Dim table As New DataTable("TEST")
    table.Columns.Add("ID", GetType(Integer))
    table.Columns.Add("VALUE", GetType(String))
    table.PrimaryKey = New DataColumn() {table.Columns(0)}
    table.Rows.Add(1, "Value 1")
    table.Rows.Add(2, "Value 2")
    table.AcceptChanges()
    Return table
End Function

Output: Count=2

编辑 - 解决方法

以下代码是解决这种奇怪(?)行为的方法。

Private Shared Sub Merge(target As DataTable, source As DataTable, preserveChanges As Boolean, msa As MissingSchemaAction)

    target.Merge(source, preserveChanges, msa)

    Dim row As DataRow
    Dim column As DataColumn
    Dim acceptChanges As Boolean

    For Each row In target.Rows
        If ((row.RowState = DataRowState.Modified) AndAlso ((row.HasVersion(DataRowVersion.Original)) AndAlso (row.HasVersion(DataRowVersion.Default)))) Then
            acceptChanges = True
            For Each column In target.Columns
                If (Not Object.Equals(row.Item(column, DataRowVersion.Original), row.Item(column, DataRowVersion.Default))) Then
                    acceptChanges = False
                    Exit For
                End If
            Next
            If (acceptChanges) Then
                row.AcceptChanges()
            End If
        End If
    Next

    acceptChanges = Nothing
    column = Nothing
    row = Nothing

End Sub

使用 DataTable 合并一段时间后,我找到了合并数据、保留更改以及不将所有现有行的 RowState 设置为 Modified 的最佳解决方案。

我发现,如果您使用 DataTable Merge 并传递 True 作为保留更改属性,则原始 DataTable 中的所有行的 RowState 都会设置为 Modified。如果您传递 false,则 RowState 保持不变。

回到文档DataTable.Merge(DataTable, Boolean, MissingSchemaAction) 方法 http://msdn.microsoft.com/en-us/library/wtk78t63%28v=vs.110%29.aspx我找到了这个:

...在这种情况下,首先调用 GetChanges 方法。该方法返回针对验证和合并而优化的第二个 DataTable。第二个 DataTable 对象仅包含已更改的 DataTable 和 DataRow 对象,从而生成原始 DataTable 的子集...

从那里我开始意识到这个合并并不是真的打算直接与原始数据一起使用...相反,您应该合并 GetChanges 方法返回的表(在保留更改时传递 true ),然后合并更改表到原始源中传递 false 以保留更改参数。

为了证明这一点,我创建了以下类:

Class TableManger
Implements ComponentModel.INotifyPropertyChanged

Private _table1 As System.Data.DataTable
Private _table2 As System.Data.DataTable
Private _changesDetected As Integer = 0

Public ReadOnly Property Table1
    Get
        Return _table1
    End Get
End Property
Public ReadOnly Property ChangesDetected As Integer
    Get
        Return _changesDetected
    End Get
End Property

Public Sub New()
    _table1 = CreateTableWithData()
    _table1.AcceptChanges()

    AddHandler _table1.RowChanged, New System.Data.DataRowChangeEventHandler(AddressOf Row_Changed)
End Sub

Public Sub MergeTables()

    _table2 = _table1.Clone
    Dim tableRows As New List(Of System.Data.DataRow)
    For Each r In _table1.Rows
        Dim dr2 = _table2.NewRow
        For Each col As System.Data.DataColumn In _table1.Columns
            dr2(col.ColumnName) = r(col.ColumnName)
        Next
        _table2.Rows.Add(dr2)
        tableRows.Add(dr2)
    Next
    _table2.AcceptChanges()


    If _table2.Rows.Count > 0 Then
        _table2.Rows(0)(1) = "TB2 Changed"
    End If

    If _table1.Rows.Count > 0 Then
        '_table1.Rows(0)(1) = "TB1 Change"'
        _table1.Rows(1)(1) = "TB1 Change"
    End If

    _changesDetected = 0
    Dim perserveChanges As Boolean = True
    Dim msAction As System.Data.MissingSchemaAction = System.Data.MissingSchemaAction.Ignore

    Dim changes As System.Data.DataTable = _table1.GetChanges()
    If changes IsNot Nothing Then
        changes.Merge(_table2, perserveChanges, msAction)
        _table1.Merge(changes, False, msAction)
    Else
        _table1.Merge(_table2, False, msAction)
    End If


    MessageBox.Show(String.Format("Changes in Change Table: {0} {1}Changes Detected: {2}", If((changes Is Nothing), 0, changes.Rows.Count), System.Environment.NewLine, _changesDetected), "Testing")

    RaiseEvent PropertyChanged(Me, New ComponentModel.PropertyChangedEventArgs("Table1"))
    RaiseEvent PropertyChanged(Me, New ComponentModel.PropertyChangedEventArgs("ChangesDetected"))
End Sub

Private Sub Row_Changed(ByVal sender As Object, ByVal e As System.Data.DataRowChangeEventArgs)
    Select Case e.Action
        Case System.Data.DataRowAction.Change
            If e.Row.RowState <> System.Data.DataRowState.Unchanged Then
                _changesDetected += 1
            End If
    End Select
End Sub

Private Function CreateTableWithData() As System.Data.DataTable
    Dim newTable As New System.Data.DataTable
    Dim columnID As New System.Data.DataColumn("ID", GetType(Guid))
    Dim columnA As New System.Data.DataColumn("ColumnA", GetType(String))
    Dim columnB As New System.Data.DataColumn("ColumnB", GetType(String))
    newTable.Columns.AddRange({columnID, columnA, columnB})
    newTable.PrimaryKey = {newTable.Columns(0)}
    For i = 0 To 5
        Dim dr = newTable.NewRow
        dr("ID") = Guid.NewGuid
        dr("ColumnA") = String.Format("Column A Row {0}", i.ToString)
        dr("ColumnB") = String.Format("Column B Row {0}", i.ToString)
        newTable.Rows.Add(dr)
    Next
    Return newTable
End Function

Public Event PropertyChanged(sender As Object, e As System.ComponentModel.PropertyChangedEventArgs) Implements System.ComponentModel.INotifyPropertyChanged.PropertyChanged
End Class

因此,在 MergeTables 方法中,我对 _table2 中的第一行进行了更改,并对 _table1 中的第二行进行了更改。

因为我对 _table1 中的第一行进行了更改,所以 _table1.GetChanges 方法返回一个包含所有更改行的 DataTable(在本例中仅是第一行)。

然后,我将包含更改的表与 _table2 合并,并指示我要保留更改。

合并完成后,我知道结果将保留合并之前所做的更改,并且该表也将包含新数据(只要不存在冲突)。将传入数据合并到更改表中的结果将解决数据中的任何冲突。

获得已解析的表后,我可以安全地合并到原始 _table1 表中,指示保留更改 = false。因为传递 false 作为保留更改参数会导致原始数据的 RowState 没有更改,所以一切都工作得很好!我的更改被保留并且 RowStates 没有被修改!

快乐编码!

-Frinny

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

在 DataRowState.Modified 中合并两个相同的 DataTables 结果 的相关文章

  • 如何在C#中模拟鼠标点击?

    如何在 C winforms 应用程序中模拟鼠标点击 我结合了多个来源来生成我当前正在使用的下面的代码 我还删除了 Windows Forms 引用 以便我可以从控制台和 WPF 应用程序使用它 而无需其他引用 using System u
  • 正则表达式 VB.Net 正则表达式.替换

    我正在尝试执行一个简单的正则表达式查找和替换 在字符串中的一些数字后面添加一个制表符 如下所述 From a users 12345 badges To a users 12345 badges 我正在使用以下内容 s regex repl
  • R data.table 计算行数,直到达到值

    我想在 data table 中返回一个新列 该列显示在达到低于当前值 Temp 的值之前有多少行 library data table set seed 123 DT lt data table Temp runif 10 0 20 这就
  • 无法加载文件或程序集“Microsoft.Office.Interop.Excel”

    我在 WinForm 应用程序中使用 Excel 时遇到问题 当我在多台计算机上尝试它时 它在它们上运行得很好 但是当我在另一台计算机上尝试它时 它会给我 System IO FileLoadException 无法加载文件或程序集 错误
  • Windows.Forms Visual Studio,如何直接在第一个窗口上打开第二个窗口?

    如何在第一个窗口的正上方打开第二个窗口 而不是在默认位置稍微对角地向右下或向后打开 我只是想制作一些可以点击的屏幕 我还应该这样做吗 为什么CenterParent不这样做呢 那么 CenterParent 会做什么呢 尝试将新表单的位置设
  • 如何在 vb.net 中更改 DateTimePicker 的日期格式

    如何更改 vb net 中 DateTimePicker 的日期格式 以便日期以 dd mm 1990 格式显示 没有任何时间值 我尝试将格式更改为 短 虽然这提供了我需要的日期格式 但它不会删除时间 您需要将 DateTimePicker
  • VB.NET 中的自动递增文本框

    单击按钮后如何增加文本框内容 将其放在按钮单击事件中 Dim int As Integer Integer TryParse TextBox1 Text int TextBox1 Text int 1
  • 如何在 C# 中从工作线程发布 UI 消息

    我正在用 C 编写一个简单的 winforms 应用程序 我创建了一个工作线程 我希望主窗口响应线程完成其工作 只需更改文本字段中的一些文本 testField Text Ready 我尝试了事件和回调 但它们都在调用线程的上下文中执行 并
  • 使用 TextBox 过滤 Datagridview 行

    我有一个绑定的 datagridView 我想使用 TextBox 值对其进行过滤 我使用了这段代码 private void ChercheStextBox TextChanged object sender EventArgs e tr
  • DataGridView:如何让回车键添加新行而不是更改当前单元格?

    如何让 Enter 键在 Winforms 中起作用DataGridViewTextBoxCell就像在普通 Winform 中一样TextBox 向文本添加新行 而不是更改当前单元格 嗯 我知道如何解决这个问题了 首先 创建一个类 名为C
  • 如何在窗体上双缓冲 .NET 控件?

    如何设置受保护DoubleBuffered遭受闪烁的窗体上的控件的属性 这是一个更通用的版本假人的解决方案 https stackoverflow com questions 76993 how to double buffer net c
  • 隐藏一个表单,切换到第二个表单,关闭第二个表单并取消隐藏第一个表单

    我已经查看了所有建议的答案 但似乎没有什么适合我正在寻找的内容 我想从主窗体中调用第二个窗体 在第二个窗体处于活动状态时隐藏主窗体 然后在第二个窗体关闭时取消隐藏主窗体 基本上我想在两种形式之间 切换 到目前为止我有 在我的主要形式中 pr
  • 与 data.table 合并时防止重复列

    我有两个数据表 它们的列名部分相似 dfA lt read table text A B C D E F G iso year matchcode 1 0 1 1 1 0 1 0 NLD 2010 NLD2010 2 1 0 0 0 1 0
  • 了解子表单何时关闭

    我有一个带有按钮的 Form1 当您单击按钮时 将执行以下代码块 Form2 frm new Form2 frm Name Form musteriNumarasi ToString frm Text Kullan c musteriNum
  • 更改数据网格列顺序或索引

    这是我无法相信我无法弄清楚的事情 请告诉我我错过了一些简单的事情 我有一个数据网格 我用 LINQ 填充它以及一个自定义类来向其中添加数据 之后 我需要按特定顺序排列数据 它似乎忽略了我 如何更改列属性 例如索引等 这是我正在使用的 LIN
  • 将非平凡函数应用于 data.table 的有序子集

    Problem 我正在尝试使用我新发现的 data table 功能 永久 来计算一堆数据的频率内容 如下所示 Sample Channel Trial Voltage Class Subject 1 1 1 196 82253 1 1 1
  • 如何在.NET中扩展环境变量%CommonProgramFiles%\system\

    我遇到一种情况 我需要通过读取注册表设置来返回目录路径 注册表值返回我以下格式的路径 CommonProgramFiles System web32 dll 而消费者代码期望它的格式为 C Program Files Common File
  • 将大数据集加载到 GridView 中的最快方法是什么?

    我有一个数据源 其中包含 1 4 数百万行 并且还在不断增长 我们让用户添加过滤器来减少调用的数据 但您仍然一次查看 43 000 到 100 000 行 在任何人说之前 无论如何没有人可以查看那么多行 它们将被导出到 Excel 工作簿中
  • 单线程公寓问题

    从我的主窗体中 我调用以下命令来打开一个新窗体 MyForm sth new MyForm sth show 一切都很好 但是这个表单有一个组合框 当我将其 AutoCompleteMode 切换为建议和追加时 我在显示表单时遇到了这个异常
  • Visual Studio 2010 设计器运行时出错

    我正在使用 VS2010 如果我在设计器模式下打开一个表单并运行我的应用程序 设计器选项卡将不再显示表单设计器 而是会显示一个错误 并且只能通过重新启动 IDE 来修复 为了防止在加载设计器之前可能发生的数据丢失 必须解决以下错误 1 Er

随机推荐

  • 使用 XSLT 转换 XML 并保留 Unicode 字符

    我的 XSLT 转换已经成功了几个月 直到我遇到带有 Unicode 字符 很可能是表情符号 的 XML 文件 我需要保留 Unicode 但 XSLT 正在将其转换为 HTML 实体 我认为将编码设置为 UTF 8 可以解决我的问题 但我
  • 为什么 copyTo(... PASTE_VALUES) 在宏中间不起作用?

    我长期使用的电子表格技术之一是就地复制 粘贴特殊值 C PSV 使用公式生成我感兴趣的值后 I C PSV 然后可以删除源数据 所以我写了一个使用这种技术的宏 但单元格最终是空的 但如果我将宏分成两个 在 C PSV 之前结束第一个宏 那么
  • 不同种类的ReaderT?

    冒着成为一个XY问题 https en wikipedia org wiki XY problem 是否有可能有一个ReaderT与不同的环境 我正在尝试类似 type AppM perms ReaderT perms IO 但是编译器抱怨
  • 如何以动态方式创建 Spring Bean。使用 Quartz SchedulerFactoryBean

    我有一个QuartzJobConfig我注册的班级Spring Quartz Beans 我按照指示SchedulerFactoryBean JobDetailFactoryBean and CronTriggerFactoryBean 我
  • 绘制动画

    我正在创建一个简单的应用程序 当用户按下按钮时 屏幕上将绘制一系列线条 并且用户将能够实时看到这些线条 几乎像动画一样 我的代码看起来像这样 已简化 UIGraphicsBeginImageContext CGSizeMake 300 30
  • 如何在Java中对多通道声音输入进行采样

    我意识到这可能是相对小众的 但这也许就是为什么无论如何都要问这个问题 我正在寻找一个硬件多输入录音控制台 例如 Alesis IO 26 来接收 Adat 光管 8 通道输入来进行信号处理 由于我还没有获得该设备 并且需要弄清楚这是否可行
  • ListView 与 getView() 由于不断的 GC 而变得缓慢?

    我的应用程序中有一个 ListView 并且我已经重写了 getView 方法 因此我可以根据行的文本更改行的 ImageView src 问题是 我注意到 ListView 滚动滞后 当我检查 DDMS 时 似乎每次滚动 ListView
  • 如何编辑 Chrome MediaRecorder 捕获的 .webm Blob

    在 Chrome 中 我在用着媒体记录器 https developer mozilla org en US docs Web API MediaStream Recording API and canvas captureStream h
  • 使用 insertUI 闪亮创建时,dragUI 不可拖动

    我用insertUI 函数来创建新的dragUI 动态地 不幸的是 新创建的dragUI行为不符合预期 我无法将它们拖动为dragUI是从创建的ui初始函数 library shiny library shinyDND ui lt flui
  • 在新窗口中打开谷歌地图。

    我创建了一个 Google Map API 我想在新选项卡 窗口 中打开它 我可以知道我的代码有什么问题吗 我可以打开新选项卡 但无法显示 Google 地图 下面是我的代码 谢谢 function newWindow var myLatl
  • 你的项目路径包含非ASCII字符android studio

    我正在安装android studio 但是当程序启动时出现这个问题 错误 1 0 您的项目路径包含非 ASCII 字符 这 很可能会导致 Windows 上的构建失败 请移动您的 项目到不同的目录 看http b android com
  • 带有简单光标适配器项目的列表视图已选中,但在滚动期间未选中

    我有一个问题 我无法在 SO 上找到答案 所有问题都在 SO 上解决 其中有太多不同的问题并且不起作用 问题是 1 ListView中被点击的行 点击后标记为蓝色背景和复选框 在滚动后失去了被点击的标记 选中的复选框和颜色 2 甚至更多 在
  • 初始化字符串的格式不符合从索引 0 开始的规范

    我有一个 ASP Net MVC 应用程序 它在我的本地开发计算机上运行良好 但是部署到IIS7后尝试登录时出现以下错误 初始化字符串格式不符合规范 从索引 0 开始 大多数发布此错误的人通过以某种方式更改连接字符串来解决它 但是 我在本地
  • 如何确定完整的 CUDA 版本 + 颠覆版本?

    Linux 上的 CUDA 发行版曾经有一个名为version txt例如 CUDA Version 10 2 89 这非常有用 但是 从 CUDA 11 1 开始 该文件不再存在 我如何在 Linux 上通过命令行确定并检查 path t
  • django OneToOne反向访问

    我有这些简单的课程 Class A models Model Class Meta models Model a models OnetoOneField A primary key True width models IntegerFie
  • python的xml.etree.ElementTree支持DTD吗?

    xml etree ElementTree 支持 DTD 吗 如果它支持 我可以强制 ElementTree 根据 dtd 文件检查 XML 文件 即使 XML 文件已经有一个 内部或外部 我不确定xml etree but lxml支持D
  • Java-使用Byteoutputstream写入大文件

    我正在尝试使用以下命令写入大小在 1kb 到 10GB 之间的文件ByteArrayOutputStream但抛出以下异常 我正在使用jdk 6 请建议任何更好的高性能Api 我使用同一个网络盒来读取和写入 Exception in thr
  • 更改本机确认/警报[重复]

    这个问题在这里已经有答案了 我想删除弹出 JavaScript 的标题 但我不知道如何才能以及在哪里编写代码 这是我的代码 a href 感谢您的帮助 你无法控制外观confirm or alert Javascript 弹出窗口 因为它们
  • 如何检查设备上是否启用了蓝牙

    我想检查设备上是否启用了蓝牙 以便应用程序可以在没有用户交互的情况下使用它 有什么办法可以做到这一点吗 我还可以分别检查蓝牙和蓝牙低功耗吗 我使用以下方法完成了此操作Radio class 检查蓝牙是否已启用 public static a
  • 在 DataRowState.Modified 中合并两个相同的 DataTables 结果

    我假设如果两个相同的话是错误的吗DataTables are merged每行的状态将被保留 看一下这个简单的例子 它创建两个相同的表并合并updated表与original桌子 但返回的表在original GetChanges is n