Сохранение DataRowState в наборе данных ADO.NET - метод RejectChanges () не работает? - PullRequest
1 голос
/ 06 августа 2009

Проблема упрощена:

У меня есть набор данных с некоторыми таблицами данных ... У меня есть DataGrid Winforms, привязанный к одной из таблиц данных. Пользователь вставляет несколько строк в указанный набор данных через DataGrid, скажем, 3 строки;

Все три строки теперь имеют свои RowState = DataRowState.Added.

Теперь я начинаю транзакцию sqlserver.

Затем вызовите dataAdapter1.Update (dataSet1), чтобы обновить строки в SqlServer. строка 1 .. ОК строка 2 .. ОК строка 3 .. ошибка на уровне sqlserver (по замыслу я ввел уникальный индекс)

При обнаружении этой ошибки я откат транзакции sqlserver.

Я также пытаюсь «откатить» изменения набора данных / набора данных, используя либо Dataset1.RejectChanges () и / или Datatable1.RejectChanges ().

Проблема не в том, что .RejectChanges () работает так, как я предполагал. Моя таблица данных теперь имеет две строки (row1, row2), RowState = DataRowState.Unchanged; row3 вообще исчез.

Я хочу, чтобы при откате транзакции sqlserver все 3 строки в таблице данных оставались в ОДНОМ СОСТОЯНИИ до вызова метода dataAdapter1.Update ().

(Причина в том, что пользователь может посмотреть на ошибку в связанной DataGrid, предпринять корректирующие действия и повторить попытку обновления).

Есть идеи у кого-нибудь? то есть я ищу что-то, эквивалентное откату состояния на уровне таблицы данных ADO.

Ответы [ 2 ]

0 голосов
/ 27 января 2012

У меня была похожая проблема с попыткой отката изменений в DataTable, который был привязан к Xceed DataGrid. После внесения изменений в DataGrid все отредактированные значения становятся частью состояния Текущее DataRow. RejectChanges применяется только для предотвращения того, чтобы состояние строки Proposed стало текущим.

Чтобы отменить изменения для данной строки, я написал метод для перезаписи текущей версии строки исходной версией. Чтобы установить версию как Original , вы просто вызываете AcceptChanges () для таблицы данных.

    public static void RevertToOriginalValues(DataRow row)
    {
        if (row.HasVersion(DataRowVersion.Original) && row.HasVersion(DataRowVersion.Current))
        {
            for (int colIndex = 0; colIndex < row.ItemArray.Length; colIndex++)
            {
                var original = row[colIndex, DataRowVersion.Original];
                row[colIndex] = original;
            }
        }
    }
0 голосов
/ 06 августа 2009

Хорошо, так что я нашел способ обойти это.

Получите клон оригинальной таблицы данных и обновите клон.

Если произошла ошибка, у вас все еще есть исходная таблица данных с ее исходным DataRowState; Кроме того, вы можете скопировать любые ошибки, возникающие в клоне, в исходную таблицу данных, отражая, таким образом, ошибки в таблице данных, которые должен видеть пользователь.

Если обновление прошло успешно, вы просто обновляете исходные данные с помощью клона.

VB код:

Try
    'daMyAdapter.Update(dsDataset, "MyDatatable") <-- replace original with below lines.
    _dtMyDatatableClone = dsDataset.MyDatatable.Copy()

    If _dtMyDatatableClone IsNot Nothing Then
      daMyAdapter.Update(_dtMyDatatableClone)

       'if you get here, update was successul - refresh now!
       dsDataset.MyDatatable.Clear()
       dsDataset.MyDatatable.Merge(_dtMyDatatableClone, False, MissingSchemaAction.Ignore)
    End If
Catch
    'uh oh, put error handler here.
End Try
...