开发者

An object with the same key already exists in the ObjectStateManager. The existing object is in the Unchanged state

开发者 https://www.devze.com 2023-01-23 19:39 出处:网络
I am trying to insert a list of entities of type foo into table TB_FOO. Public Sub Insert(ByVal _lstFoo As List(Of TB_FOO))

I am trying to insert a list of entities of type foo into table 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_FO开发者_运维问答O = _lstFoo(i)        
        _MyEntityManager.AddToTB_FOO(foo)
      Next
      _MyEntityManager.SaveChanges()
      _MyEntityManager.AcceptAllChanges()
    Catch ex As Exception
      Debug.WriteLine(ex.StackTrace)
    End Try

  End Sub

In the foo object there are 2 relationships. One is to the entity TB_FOO2 which is an object that was just inserted earlier in the code and another is TB_FOO3 which was selected from the database.

On the first iteration of the loop when it arrives to _MyEntityManager.AddToTB_FOO(foo) it throws the error

An object with the same key already exists in the ObjectStateManager. The existing object is in the Unchanged state. An object can only be added to the ObjectStateManager again if it is in the added state.

Any ideas why this error is thrown?


You are probably re-using an old ObjectContext.

This line:

_MyEntityManager.AddToTB_FOO(foo)

… Will fail if there is already an entity with the same primary key value as foo in the context. It will also fail if foo is related, via a navigation property, to some other entity which is detached, but which has a "twin" entity in the context with the same primary key value.

The simplest way to not have these problems is to use a new ObjectContext instance for the whole method and to dispose it when you're done. Long-lived ObjectContexts almost invariably lead to memory leaks and really confusing errors.


i'm using this because I have already created a new instance, and populated the properties I need to update.

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

this is a newer version of EF it seems, or just a different model. It's also translated from C# mostly, but hopefully it helps.

0

精彩评论

暂无评论...
验证码 换一张
取 消