3
votes

Comment libérer des entités suivies?

Espérons que l'extrait de code suivant soit suffisamment clair pour expliquer le problème. _db est une instance de DbContext.

// this scenario is only for learning purpose
Author a = _db.Authors.Find(1831);
int id = a.AuthorId;
a = null;

Author stub = new Author { AuthorId = id };
_db.Remove(stub);
_db.SaveChanges();

Le code ci-dessus produit

'L'instance du type d'entité' Author 'ne peut pas être suivie car une autre instance avec la même valeur de clé pour {' AuthorId '} est déjà en cours de suivi. Lorsque vous attachez des entités existantes, assurez-vous qu'une seule instance d'entité avec une valeur de clé donnée est attachée. Pensez à utiliser "DbContextOptionsBuilder.EnableSensitiveDataLogging" pour voir les valeurs de clé en conflit. "

Question

Comment libérer un du suivi?


4 commentaires

_db.Entry (a) .State = EntityState.Detached


@ Zer0: Merci. C'est très utile. :-)


@ Zer0: Si vous n'êtes pas intéressé à poster votre commentaire comme réponse, je supprimerai cette question sous peu. Je vous remercie.


Je déciderai de la réponse acceptée dans quelques heures.


3 Réponses :


2
votes

Vous pouvez essayer AsNoTracking () .
_db.Authors.AsNoTracking (). Où (a => a.AuthorId == 1831) .FirstOrDefault ();


0 commentaires

2
votes

Vous devez utiliser l'option AsNoTracking lors de la recherche d'un.

par exemple La requête ci-dessous obtient tous les éléments du blog, mais si vous essayez de les supprimer, vous ne devriez obtenir aucune erreur.

context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

var blogs = context.Blogs.ToList();

Vous pouvez définir AsNoTracking soit sur requête, soit il peut également être défini sur l'objet de contexte comme indiqué ci-dessous:

var blogs = context.Blogs
        .AsNoTracking()
        .ToList();

Cela devrait vous aider à résoudre ce problème.

Consultez cette page MSDN pour plus de détails.


0 commentaires

3
votes

Il existe plusieurs façons de procéder, mais je trouve que c'est la plus simple car vous essayez de détacher une entité spécifique.

_db.Entry(a).State = EntityState.Detached

En plus, cela ne nécessite pas modifier tout autre code, y compris la manière dont vous avez récupéré l'entité elle-même.

Cette seule ligne rend très clair l'intention. Il permet également ce qui suit:

  1. Récupérer une entité ou une liste d'entités
  2. Effectuer différents types de travaux
  3. Détacher une entité

Je n'aime pas l'idée de modifier les requêtes existantes sur un DbContext quand tout ce que je veux faire est de détacher quelque chose.


0 commentaires