ObjectStateManager中已存在具有相同键的对象。现有对象处于Unchanged状态

时间:2010-11-08 10:03:31

标签: .net entity-framework

我正在尝试将foo类型的实体列表插入到表TB_FOO中。

    Public Sub Insert(ByVal _lstFoo As List(Of TB_FOO))

    Try
      For i As Integer = 0 To _lstFoo.Count - 1
        Dim foo As TB_FOO = _lstFoo(i)        
        _MyEntityManager.AddToTB_FOO(foo)
      Next
      _MyEntityManager.SaveChanges()
      _MyEntityManager.AcceptAllChanges()
    Catch ex As Exception
      Debug.WriteLine(ex.StackTrace)
    End Try

  End Sub

在foo对象中有2个关系。一个是实体TB_FOO2,它是刚刚在代码中插入的对象,另一个是从数据库中选择的TB_FOO3。

在循环的第一次迭代到达_MyEntityManager.AddToTB_FOO(foo)时,它会抛出错误

  

具有相同密钥的对象   存在于ObjectStateManager中。该   现有对象在Unchanged中   州。只能添加对象   如果是,则再次返回ObjectStateManager   在增加的状态。

为什么会抛出这个错误?

2 个答案:

答案 0 :(得分:8)

您可能正在重复使用旧的ObjectContext

这一行:

_MyEntityManager.AddToTB_FOO(foo)

...如果在上下文中已存在与foo具有相同主键值的实体,则会失败。如果foo通过导航属性与另一个分离的实体相关联,但在上下文中具有相同主键值的“双胞胎”实体,它也将失败。

没有这些问题的最简单方法是为整个方法使用一个新的ObjectContext实例,并在完成后处理它。长期存在的ObjectContext几乎总是会导致内存泄漏,并且真正令人困惑。

答案 1 :(得分:0)

我正在使用它,因为我已经创建了一个新实例,并填充了我需要更新的属性。

Public Sub Insert(ByVal _lstFoo As List(Of TB_FOO))

Try
  For i As Integer = 0 To _lstFoo.Count - 1
    Dim foo As TB_FOO = _lstFoo(i) 
    ObjectStateEntry ose;  
    Dim key=CreateEntityKey("TB_FOOs",foo); 
    if(ObjectStateManager.TryGetObjectStateEntry(key, out ose)) then
       Dim entity=(TB_FOO)ose.Entity;
       TF_FOOs.Detach(entity);
    end if
    _MyEntityManager.AddToTB_FOO(foo)
  Next
  _MyEntityManager.SaveChanges()
  _MyEntityManager.AcceptAllChanges()
Catch ex As Exception
  Debug.WriteLine(ex.StackTrace)
End Try

End Sub

这是EF的新版本,或者只是一个不同的型号。它也主要是从C#翻译而来,但希望它有所帮助。