Я ошибаюсь, полагая, что если два идентичных DataTables
объединены, состояние каждой строки будет сохранено?Объединить два идентичных результата DataTables в DataRowState.Modified
Взгляните на этот простой пример. Он создает две идентичные таблицы и объединяет таблицу updated
с таблицей original
. Но возвращенная таблица в original.GetChanges()
не 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
Выход: Count=2
Edit - Обходной
Следующий код обходной путь для этого странного поведения (?).
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
Продолжение с этим и по какой-то причине, если вы установите PreserveChanges = ложь строки не приготовьтесь к модифицирован после слияния ... Однако, если вы указываете, что PreserveChanges = истина (что бы вы думали бы сохранить изменения), строки становятся модифицированными. Я не смог воспроизвести вашу проблему, потому что я устанавливал perserveChanges = false в своем первоначальном тестировании .... Я нахожу, что эта функция слияния отсутствует в документации, и она, похоже, не работает интуитивно (т.е.: save changes = true устанавливает все на «измененные» и сохраняет изменения = false оставляет их в покое) – Frinavale
Если вы установите perserveChanges = False, любые изменения в исходной таблице будут перезаписаны объединенными данными, но строки не будут изменены. Если вы установите perserveChanges = True, исходные данные не будут перезаписаны входящими данными. И по каким-то причинам состояния строк настроены на изменение. – Frinavale