0

テーブル アダプターを想定どおりに使用していないような気がします。私はここでいくつかの質問を読みました.datagridviewの(DGV)での同時実行エラーの処理に関するこのMSの記事。

私のセットアップでは、一度に 1 人のユーザーのみがテーブルにアクセスし、その人が作業しているローカル HD にアクセスします。タブコントロールの複数のタブで複数の DGV を使用しています。DGV は Access DB のテーブルにバインドされています。ユーザーが 2 つ以上の行にまたがる複数のセルに値を入力しようとすると、2 行目の 2 番目のセルの後で同時実行エラーが発生します。同時実行エラーを一度処理し、主キー列を更新する DGV を再入力すると、エラーは発生しなくなります。

DGV の既存の値に戻ってもエラーは発生しません。キー列 (ユーザーは入力しませんが、並べ替えることができます) の場合にのみ発生するようですIs DBNull

ここに私がこれまでに持っているものがあります:

Dim m_DtChemical As New DataTable
Dim ChemicalAdapter As OleDbDataAdapter
Dim m_Bsource As New BindingSource

Sub FillChemicalDataGrid()
    ChemicalAdapter = New OleDbDataAdapter("Select * From Chemicals", ConMain)
    m_DtChemical.Clear()
    ChemicalAdapter.Fill(m_DtChemical)
    m_Bsource.DataSource = m_DtChemical
    ChemicalDataGridView.DataSource = m_Bsource
End Sub


Sub UpdateChemicalsDatabase()
    Try
        Dim ObjComander As New OleDbCommandBuilder(ChemicalAdapter)
        ChemicalAdapter.Update(m_DtChemical)

    Catch ex2 As DBConcurrencyException
        OhGodImStuckErrorHandler()
        MsgBox("Concurrency Error.  Reloading Table.")
        FillChemicalDataGrid()

    Catch ex As Exception
        MsgBox("There was an error updating to the database. " & ex.Message)
        WriteToErrorLog(ex.Message, ex.StackTrace, ex.GetHashCode, ex.Source, ex.ToString)
    End Try

End Sub

Private Sub ChemicalDataGridView_RowValidated(ByVal sender As Object, ByVal e As _
System.Windows.Forms.DataGridViewCellEventArgs) Handles ChemicalDataGridView.RowValidated 'tried CellLeave, CellEnter, CellValidated...etc
    Call UpdateChemicalsDatabase()
End Sub

特に、マージと更新を実行しようとしましたIf IsDBNull(DGV(0, Xrow).Value) = true

私はやろうとしていることから離れていますか?ID (主キー列) が実際に DBNull であるインスタンスからのみのようです。これを処理するより良い方法はありますか?同時実行エラーを処理するというよりは、方法さえわかれば、そもそも回避できるはずだという気がします。

VB.net と C# で同様のプロジェクトがあり、どちらもまったく同じ問題を抱えています。私はVB.Netの方が少し快適ですが、エーテルで答えていただければ幸いです。

編集:コメントに応じてシナリオを説明する:

したがって、ユーザーが入ってきて、DGV の新しい行 (名前など) のセルに入力します。彼らが1行だけを埋めると、すべてが正しく更新/挿入され、DBはそれにIDを割り当て、次にアクセスしたときに表示されます。新しい行ごとに複数の列に書き込もうとすると、同時実行エラーがスローされます。新しい行が追加されるたびに、DGV の ID は DBNull になりますが、更新または入力されると、DB によって生成された ID が使用されることに注意してください。DGV が ID 列に正しいキーを表示している場合、同時実行エラーが発生することはありません。

4

2 に答える 2

1

並行性の問題を処理する 1 つの方法は、ダーティ行を特定することです。

何かが汚れているかどうかを確認する 1 つの方法は、クエリ中に行のタイムスタンプを取得することです (つまり、行にタイムスタンプ列があり、更新中にこの列が getdate() に設定されます)。

アプリケーションで実際の更新を行う前に、最初に更新しようとしている行のタイムスタンプをロードし、行のタイムスタンプが DB のタイムスタンプと一致する場合は、ダーティがないことがわかります。更新を続行できます。

汚れた行がある場合..それを処理する方法について考えることがいくつかあります...のように-多分

  1. ダーティでない行のみを更新する
  2. 更新プロセス全体を停止し、更新された行を再ロードして、これらの行が更新されたことをユーザーに通知します。
  3. または、ユーザーが変更を取得せずに他のユーザーのデータを実際に上書きできるようにします。

あなたの要件に応じてあなた次第。

于 2013-10-04T09:58:07.640 に答える
1

問題は、「キー列」で DBNull が許可されていることです。MS がレコードをマージし、同じレコードが複数回存在しないようにするには、主キー列が必要です。

ここで起こっているのは、キャッシュに同じレコードが複数回あり、1 つのレコードを更新すると、他のレコードが同期されないということです。単一のデータセットを使用し、各データテーブルに主キーを適用することで、複数のデータのコピーを排除できます。DataAdapter.Fill() のようなことをすると、MS は同じレコードをやみくもに追加するだけでなく、データをマージします。次に保存すると、レコードのフラグが更新およびリセットされるため、次回保存するときに同時実行エラーが発生することはありません。

于 2013-10-08T18:04:21.803 に答える