Поведение 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 заставляет список терять текущий выбор пользователя. Таким образом, я реализовал (безобразный) обходной путь, который в основном состоит из

  1. изменение поля в DataTable на значение, которое я знаю, что это поле никогда не будет иметь
  2. Бег .Fill
  3. удаление всех строк, содержащих это значение

Другими словами:

    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

Любые предложения для более элегантных решений приветствуются.

Другие вопросы по тегам