1

問題は単純化されました:

いくつかのデータテーブルを含むDataSetがあります...データテーブルの1つにバインドされたWinformsDataGridがあります。ユーザーは、DataGridを介して、いくつかの行を上記のデータテーブルに貼り付けます。たとえば、3行とします。

これで、3つの行すべてにRowState=DataRowState.Addedがあります。

ここで、sqlserverトランザクションを開始します。

次に、dataAdapter1.Update(dataSet1)を呼び出して、行をSqlServerに更新します。行1..OK行2..OK行3..sqlserverレベルでのエラー(設計上、一意のインデックスを適用しました)

このエラーを検出したら、sqlserverトランザクションをロールバックします。

また、Dataset1.RejectChanges()および/またはDatatable1.RejectChanges()のいずれかを使用して、データテーブル/データセットの変更を「ロールバック」しようとします。

問題は、.RejectChanges()が私が想定したように機能することではありません。私のデータテーブルには2つの行(row1、row2)があり、そのRowState = DataRowState.Unchanged; row3は完全に消えました。

私がしたいのは、sqlserverトランザクションをロールバックするときに、dataAdapter1.Update()メソッドを呼び出す直前にデータテーブルの3行すべてが同じ状態のままになることです。

(理由は、ユーザーがバインドされたDataGridのエラーを確認し、修正アクションを実行して、更新を再試行できるようにするためです)。

誰かアイデアはありますか?つまり、ADOdataTableレベルで状態をロールバックするのと同等のものを探しています。

4

2 に答える 2

0

XceedDataGridにバインドされたDataTableへの変更をロールバックしようとしたときに同様の問題が発生しました。DataGridで編集が行われると、編集された値はすべてDataRowの現在の状態の一部になります。RejectChangesは、提案された行の状態が現在になるのを防ぐためにのみ適用できます。

特定の行の変更を元に戻すために、現在の行のバージョンを元のバージョンで上書きするメソッドを作成しました。バージョンを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;
            }
        }
    }
于 2012-01-27T19:13:51.443 に答える
0

さて、これを回避する方法を考えました。

元のデータテーブルのクローンを取得し、クローンを更新します。

エラーが発生した場合でも、元のDataRowStateを含む元のデータテーブルがあります。さらに、クローンで発生したエラーを元のDatatableにコピーして、ユーザーが確認できるようにデータグリッドのエラーを反映することができます。

更新が成功した場合は、元のデータテーブルをクローンで更新するだけです。

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
于 2009-08-06T06:30:14.303 に答える