Поведение DataAdapter.Fill() для строки, удаленной в источнике данных
Я использую DataSet
/DataTable
/DataAdapter
архитектура для связи между базой данных и объектами моей модели, которые имеют свою собственную поддержку (они не поддерживаются DataRow). у меня есть DataAdapter
с AcceptChangesDuringFill = False
, AcceptChangesDuringUpdate = False
, а также FillLoadOption = OverwriteChanges
, Вот мое понимание DataAdapter
Модель в этих условиях:
DataAdapter.Update ()
DataRowState.Added
приведет кInsertCommand
обжигDataRowState.Modified
приведет кUpdateCommand
обжигDataRowState.Deleted
приведет кDeleteCommand
обжиг
DataAdapter.Fill()
- Любая строка в возвращенном наборе результатов, чей первичный ключ соответствует существующей строке в
DataTable
будет использоваться для обновления этой строки, и состояние этой строки всегда будетDataRowState.Modified
, даже если возвращенная строка идентична текущей строке - Любая строка в возвращенном наборе результатов, чей первичный ключ не соответствует какой-либо существующей строке, будет использоваться для создания новой строки, и состояние этой строки станет
DataRowState.Added
- Любая строка в
DataTable
который не соответствует строке в возвращенном наборе результатов, останется вDataRowState.Unchanged
Учитывая, что я прав в этой ментальной модели, предположим, что я хочу использовать Fill()
замечать удаленные строки в источнике данных. Также предположим, что параметры SelectCommand
не возвращайте всю таблицу. Я предполагаю, что у меня есть два варианта:
- Найдите все строки, которые должны были быть обновлены
Fill()
но все ещеDataRowState.Unchanged
(опирается на мое непроверенное выделенное курсивом предположение выше). Эти строки были удалены в источнике данных. - Очистить все соответствующие строки из
DataTable
передFill()
; любая строка, которая больше не появляется, была удалена в источнике данных. Это теряет различие междуDataRowState.Added
а такжеDataRowState.Modified
это сохраняется с первым методом.
Итак, мои вопросы:
- Является ли моя модель выше
DataAdapter
правильно, с учетом значений свойств, которые я отметил в верхней части? - Какой вариант мне выбрать, чтобы найти удаленные строки? Я бы предпочел первый, но это зависит от моего предположения, что все возвращаемые строки будут установлены в
DataRowState.Modified
даже если строка идентична; это безопасное предположение? - Я все об этом ошибаюсь?
2 ответа
Оказывается, мое предположение ошибочно, если строка, возвращаемая SelectCommand
точно так же, как ряд уже в DataTable
этот ряд остается отмеченным как DataRowState.Unchanged
, Таким образом, правильная процедура удаления строк из DataTable
перед звонком Fill()
и определение судьбы ряда путем сравнения нового набора DataRowState.Added
строки к прежнему списку строк.
Я вижу похожую проблему, но не могу использовать .Clear
так как DataTable
привязан к списку пользовательских интерфейсов и .Clear
с последующим .Fill
заставляет список терять текущий выбор пользователя. Таким образом, я реализовал (безобразный) обходной путь, который в основном состоит из
- изменение поля в DataTable на значение, которое я знаю, что это поле никогда не будет иметь
- Бег
.Fill
- удаление всех строк, содержащих это значение
Другими словами:
For Each drow As DataRow In dset.Tables(0).Rows
drow.Item("myField") = -1
Next
myDataAdapter.Fill(dset)
Dim drowsRemove = (From drow In dset.Tables(0).AsEnumerable() _
Where drow.Field(Of Integer)("myField") = -1).ToList()
For Each drow In drowsRemove
dset.Tables(0).Rows.Remove(drow)
Next
Любые предложения для более элегантных решений приветствуются.