Un objet avec la même clé existe déjà dans ObjectStateManager. L'objet existant est à l'état Inchangé

.net entity-framework

Question

J'essaie d'insérer une liste d'entités de type foo dans la 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_FOO = _lstFoo(i)        
        _MyEntityManager.AddToTB_FOO(foo)
      Next
      _MyEntityManager.SaveChanges()
      _MyEntityManager.AcceptAllChanges()
    Catch ex As Exception
      Debug.WriteLine(ex.StackTrace)
    End Try

  End Sub

Dans l'objet foo, il y a 2 relations. L'une concerne l'entité TB_FOO2 qui est un objet qui a été inséré précédemment dans le code et l'autre est TB_FOO3 qui a été sélectionnée dans la base de données.

Lors de la première itération de la boucle quand elle arrive à _MyEntityManager.AddToTB_FOO(foo) , l'erreur est _MyEntityManager.AddToTB_FOO(foo) .

Un objet avec la même clé existe déjà dans ObjectStateManager. L'objet existant est à l'état Inchangé. Un objet ne peut être ajouté à nouveau à ObjectStateManager que s'il est dans l'état ajouté.

Des idées pourquoi cette erreur est jetée?

Réponse acceptée

Vous réutilisez probablement un ancien ObjectContext .

Cette ligne:

_MyEntityManager.AddToTB_FOO(foo)

• échouera s'il existe déjà une entité avec la même valeur de clé primaire que foo dans le contexte. Il échouera également si foo est lié, via une propriété de navigation, à une autre entité qui est détachée, mais qui possède une entité "jumelle" dans le contexte avec la même valeur de clé primaire.

Le moyen le plus simple de ne pas avoir ces problèmes est d'utiliser une nouvelle instance d' ObjectContext pour l'ensemble de la méthode et de la supprimer lorsque vous avez terminé. La longue durée de vie des ObjectContext entraîne presque invariablement des fuites de mémoire et des erreurs vraiment déroutantes.


Réponse populaire

J'utilise ceci parce que j'ai déjà créé une nouvelle instance et renseigné les propriétés que je dois mettre à jour.

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

c'est une nouvelle version de EF, semble-t-il, ou juste un modèle différent. Il est également traduit du C # principalement, mais j'espère que cela aide.



Related

Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow
Sous licence: CC-BY-SA with attribution
Non affilié à Stack Overflow