2

私のアプリケーションには、データベース テーブルの内容をユーザーに表示するコントロールがあります。このコントロールは、System.Data.DataSetオブジェクトに表示するデータを保持します。ユーザーは、コントロールに表示されたデータを変更できます。ユーザーの操作が完了すると、このデータはデータベースにコミットされます。

ユーザーがコントロールで編集を行っているときに、データベース テーブルのデータが外部プロセスによって変更されると (たとえば、いくつかの行が更新されるなど)、問題が発生します。ここでは、データの正確性の問題を無視して、ユーザーがコントロールで行った変更をコミットし、この外部プロセスによって行われた変更を上書きします。

を使用しSqlDataAdapterてデータベースを更新しています。説明されている使用例では、基になるデータベース テーブルが外部プロセスによって変更されていない場合、SqlDataAdapter.Update期待どおりに動作します。ただし、ユーザーがテーブルを編集しているときに外部プロセスがテーブルをいじったシナリオではSqlDataAdapter.Update、例外はスローされず、行が更新されなかったことを示す 0 が返されます。データセットの行に正しいデータが含まれていることを確認したのでRowState(つまりDataRowState.Modified)、メソッドに渡すデータが正しいことがわかりSqlDataAdapter.Updateます。

私の質問には2つの部分があると思います。

  1. SqlDataAdapter.Update指定されたデータセットでデータベースを更新しないのはなぜですか?
  2. なぜ静かに失敗するのですか?

このブログ エントリを読みましたが、私のコードはAcceptChangesどこにも呼び出されません。上で述べたように、 をチェックしたので、行が変更されたデータとして正しくマークされていることがわかりましたDataSetRowState

4

1 に答える 1

1

テーブルの構造と、使用しているバージョン管理メカニズム (タイムスタンプ、日時など) は何ですか? が最終的にバージョン管理を処理する方法に影響を与える可能性のあるものはたくさんありますがSqlDataAdapter、私の推測では、テーブルにタイムスタンプがあるか、 (メソッドを介して) をSqlCommandBuilder生成している があり、最終的には更新した行の以前の値に対してデータベース内の行を比較します (比較のために以前のバージョンの行が保存されます)。SqlCommandGetUpdateCommandDataRow

ADO.NET はオプティミスティックコンカレンシーを維持しようとするため、これらすべてが役割を果たします。最後にレコードをフェッチしてから他の誰かがレコードを変更した場合、更新は行われません。

これは明らかに望んでいる動作ではありません。後攻のアプローチが必要です。

これを行うには、更新を実行し、タイムスタンプをチェックしないプロパティを明示的にSqlDataAdapter設定すると、主キーが指定した値 (または列の値) と等しいレコードのみが更新されます。一意の制約があります)。UpdateCommandSqlCommandDataRow

于 2011-08-11T12:45:55.263 に答える