4

DataSet//アーキテクチャを使用してDataTableDataAdapterデータベースとモデル オブジェクトの間を仲介しています。これらは独自のバッキングを持っています (DataRow によってバッキングされていません)。、、および がありDataAdapterます。これらの条件下でのモデルの私の理解は次のとおりです。AcceptChangesDuringFill = FalseAcceptChangesDuringUpdate = FalseFillLoadOption = OverwriteChangesDataAdapter

DataAdapter.Update()

  • DataRowState.AddedInsertCommand発砲につながります
  • DataRowState.ModifiedUpdateCommand発砲につながります
  • DataRowState.DeletedDeleteCommand発砲につながります

DataAdapter.Fill()

  • 主キーが の既存の行に対応する返された結果セットの行は、その行の更新に使用され、返された行が現在の行と同一であってもDataTableその行の状態は常に になります。DataRowState.Modified
  • 主キーが既存の行に対応しない、返された結果セット内の行は、新しい行の作成に使用され、その行の状態は次のようになります。DataRowState.Added
  • DataTable返された結果セットの行に対応しない行はそのまま残ります。DataRowState.Unchanged

このメンタル モデルで私が正しいとすればFill()、データ ソース内の削除された行を通知するために を使用するとします。また、 のパラメータがSelectCommandテーブル全体を返さないとします。次の 2 つのオプションがあると思います。

  • Fill()によって更新されるべきであるが、まだ更新されているすべての行を見つけますDataRowState.Unchanged(上記のテストされていないイタリック体の仮定に依存しています)。これらの行はデータ ソースで削除されています。
  • ;のDataTable前の関連行をすべてクリアします。Fill()再び表示されない行は、データ ソースで削除されています。これにより、最初の方法で保持されている とDataRowState.Addedの区別が失われます。DataRowState.Modified

だから、私の質問:

  • 上記のモデルは、DataAdapter上部に記載したプロパティ値の対象となりますか?
  • 削除された行を見つけるには、どのオプションを使用すればよいですか? 私は最初のものを好みますが、それはDataRowState.Modified、行が同一であっても、返されるすべての行がに設定されるという私の仮定に依存しています。それは安全な仮定ですか?
  • 私はこれについてすべて間違っていますか?
4

2 に答える 2

1

私の仮定は間違っていることがわかりました。 によって返されSelectCommandた行が にすでにある行とまったく同じであるDataTable場合、その行は としてマークされたままになりDataRowState.Unchangedます。したがって、適切な手順は、DataTableを呼び出す前にから行を削除し、新しい行のセットを以前の行のリストとFill()比較して行の運命を判断することです。DataRowState.Added

于 2009-07-08T01:20:40.347 に答える
1

同様の問題が発生しますが、 がユーザー インターフェイス リストにバインドされており、その後にリストがユーザーの現在の選択を失うため、.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

よりエレガントなソリューションの提案は大歓迎です。

于 2009-08-14T20:08:39.913 に答える