我正在开发一个使用 ADO.NET (raw sql) 和 Active Record 模式构建的项目。我正在慢慢地将它从 ADO.NET 移到 Entity Framework Code First 4.3。
这是该模式的示例。该接口是一个静态加载和一个实例保存(和删除——未显示)。
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(...)
行,它工作正常。
是否有某种类型的更改跟踪器存在于我不知道的上下文之外?这似乎会扼杀任何对 Active Record 模式的尝试。
我也愿意接受有关如何使 Active Record 与 EF 一起使用的任何建议。这context.Entry
条线很糟糕,但我不知道还能做什么。
告诉我不要做 Active Record 没有帮助,但请随意。