0

我正在使用ADO.NET(原始sql)和Active Record模式構建的項目。我正慢慢將它從ADO.NET轉移到Entity Framework Code First 4.3。使用實體框架的Active Record

這是一個模式的例子。該接口是一個靜態加載和一個實例保存(和刪除 - 未顯示)。

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 

我認識活動記錄是不理想的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(...)線,它工作正常。

是否有某種類型的更改跟蹤器,它們位於我不知道的上下文之外?這似乎會殺死任何在Active Record模式下的企圖。

我也歡迎任何關於如何使用Active Record與EF一起工作的建議。 context.Entry行很糟糕,但我不知道還有什麼要做。

告訴我不要做活動記錄是沒有用的,但感覺自由。

回答

0

我相信實體框架可能仍然在跟蹤您加載它的上下文中的對象,因爲您爲每個加載和保存調用創建了一個新的上下文。如果是這種情況,請嘗試在加載對象後卸下對象:

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 
+0

我會給出一個鏡頭,謝謝。 – anonymous

+0

看起來我之前使用ObjectContext語法進行分離 - 使用新代碼進行更新,因爲我只需要使用它自己 – Richard