1

行バージョンまたはタイムスタンプなしで SQL テーブルを使用しています。ただし、テーブル内の特定の値を更新するには、Linq を使用する必要があります。Linq は更新する値を認識できないため、2 番目の DataContext を使用してデータベースから現在のオブジェクトを取得し、次のようにデータベースと実際のオブジェクトの両方を Attach メソッドの入力として使用しています。

Public Sub SaveCustomer(ByVal cust As Customer)
    Using dc As New AppDataContext()
        If (cust.Id > 0) Then
            Dim tempCust As Customer = Nothing

            Using dc2 As New AppDataContext()
                tempCust = dc2.Customers.Single(Function(c) c.Id = cust.Id)
            End Using

            dc.Customers.Attach(cust, tempCust)
        Else
            dc.Customers.InsertOnSubmit(cust)
        End If

        dc.SubmitChanges()
    End Using
End Sub

これは機能しますが、問題があります。StoredProcedures を使用して、特定の時間に Customer の一部のフィールドを更新しています。次のワークフローを想像してください。

  1. データベースから顧客を取得
  2. 顧客フィールドを新しい値に設定する
  3. ストアド プロシージャを使用して別の顧客フィールドを更新する
  4. SaveCustomer を呼び出す

ここで、SaveCustomer メソッドは、コードで設定された値を含まないが、ストアド プロシージャによって設定された値を含む現在のオブジェクトをデータベースから取得します。これを実際のオブジェクトにアタッチしてから送信すると、コードで設定された値がデータベースでも更新され、... tadaaaa... 他の値が NULL に設定されます。ストアド プロシージャ。

それは理解できましたか?

この問題を解決するためのベスト プラクティスはありますか?

4

2 に答える 2

0

オブジェクトをあるコンテキストから切断し、別のコンテキストを更新に使用する場合は、元のオブジェクトを保持するか、行バージョンを使用するか、データベースに何らかのハッシュルーチンを実装して、ハッシュを一部として保持する必要があります。あなたのオブジェクトの。これらのうち、Rowversionオプションも強くお勧めします。あなたがやろうとしているように現在の値を元の値として使用することは、並行性の問題を求めるだけです。

于 2009-07-31T00:05:41.323 に答える
0

ORM の背後で変更を行い、並行性チェックを使用しない場合、問題が発生します。ステップ「3」で何をしたかは示していませんが、IMO では、おそらくOUTPUTTSQL パラメータを使用して、これらの変更を反映するようにオブジェクト モデルを更新する必要があります。または; オブジェクト指向に固執する。

もちろん、並行性チェックなしで何かを行うこと、データを失う良い方法です。それ以外の場合は、おそらく更新されたオブジェクトを読み込んでマージすることができます...どういうわけか正しいデータが何であるかを推測します...rowversion

于 2009-07-13T09:38:50.290 に答える