0

ADO.NET (raw sql) と Active Record パターンを使用して構築されたプロジェクトに取り組んでいます。ADO.NET から Entity Framework Code First 4.3 にゆっくりと移行しています。

パターンの例を次に示します。インターフェイスは、静的な Load とインスタンスの Save (および Delete -- 表示されていません) です。

Public Class Part
    Public Property Id as Integer

    Public Shared Function Load(_id As Integer) As Part
        Using context As New DataContext()
            Return context.Find(_id)
        End Using
    End Function

    Public Sub Save()
        Using context As New DataContext()
            If Id = 0 Then
                context.Parts.Add(Me)
            Else
                context.Entry(Me).State = Data.EntityState.Modified
            End If

            context.SaveChanges()
        End Using
    End Sub
End Class

Active Record は EF にとって理想的ではないことは理解していますが、残りのコードには触れずに、ADO.NET コードをすべて削除できるようにしたいと考えています。

これはほとんど機能しますが、解決方法がわからない問題に遭遇しました。外部キーの同期を維持するために、次のように処理します。

Public Sub Save()
    ParentPart = Part.Load(ParentPartId)
    ChildPart = Part.Load(ChildPartId)

    Using context = New iTracContext()

        If bid = 0 Then
            context.BillOfMaterials.Add(Me)
        Else
            context.Entry(Me).State = Data.EntityState.Modified
        End If

        context.SaveChanges()
    End Using
End Sub

これにより、一致しないリレーションシップがあることを EF が訴えることがなくなります。ID が常に優先されます。

問題は、保存時に例外がスローされることです。

同じキーを持つオブジェクトが ObjectStateManager に既に存在します。ObjectStateManager は、同じキーを持つ複数のオブジェクトを追跡できません。

これは次の行からスローされます。

context.Entry(Me).State = Data.EntityState.Modified

ObjectStateManagerこのコンテキストの何かはどうですか? それは真新しく、空であるべきですよね?

Part.Load(...)2行を削除すると、正常に機能します。

私が気付いていないコンテキストの外にあるタイプの変更トラッカーはありますか? それは、Active Record パターンでのあらゆる試みを殺してしまうようです。

Active Record を EF で動作させる方法についての提案もお待ちしています。ラインはひどいですが、context.Entry他に何をすべきかわかりません。

Active Record をしないように言っても何の役にも立ちませんが、遠慮なく言ってください。

4

1 に答える 1

0

Load と Save の呼び出しごとに新しいコンテキストを作成するため、Entity Framework は、読み込んだコンテキストからオブジェクトを追跡している可能性があると思います。このような場合は、オブジェクトをロードした後に切り離してみてください。

Public Shared Function Load(_id As Integer) As Part
    Using context As New DataContext()
        Part part = context.Find(_id)
        context.Entry(part).State = EntityState.Detached ' Detach from the initial context
        Return part
    End Using
End Function
于 2012-05-14T21:32:31.717 に答える