web-dev-qa-db-fra.com

Un objet avec la même clé existe déjà dans ObjectStateManager. ObjectStateManager ne peut pas suivre plusieurs objets avec la même clé

J'ai le code suivant pour ajouter ou mettre à jour l'objet Entity. trouver l'objet par clé primaire, en fonction de la réponse que j'ajoute ou met à jour l'objet.

L'ajout d'enregistrements fonctionne, mais lors de la mise à jour, ce message d'erreur " Un objet avec la même clé existe déjà dans ObjectStateManager. ObjectStateManager ne peut pas suivre plusieurs objets avec la même clé"

Dans ma base de données MSSQL, je n'ai qu'un seul enregistrement.

var v = db.Envelopes.Find(model.ReportDate, model.Service);
if (v == null)
{
    db.Envelopes.Add(model);
    db.SaveChanges();
    ViewBag.status = "Record Add successfully";
    ModelState.Clear();
}
else
{
    db.Entry(model).State = EntityState.Modified;
    db.SaveChanges();
}

Comment puis-je résoudre ce message d'erreur?

52
sfgroups

Comme mentionné par @anon, vous ne pouvez pas attacher de modèle une fois que vous avez chargé l'entité avec la même clé. Les modifications doivent être appliquées à l'entité attachée. Au lieu de cela:

db.Entry(model).State = EntityState.Modified;

utilisez ceci: 

db.Entry(v).CurrentValues.SetValues(model);
88
Ladislav Mrnka

Si une requête précédente a lu l'entité à mettre à jour et que c'est la raison pour laquelle vous obtenez l'erreur, vous pouvez modifier cette requête en AsNoTracking. Voir l'exemple AsNoTracking dans: http://www.asp.net/entity-framework/tutorials/advanced-entity-framework-scenarios-for-an-mvc-web-application

9
tdykstra

Je suppose que vous dites que votre erreur se produit ici:

db.Entry(model).State = EntityState.Modified;

Une fois que vous avez exécuté Find (), votre enveloppe est déjà suivie par votre contexte. Cela signifie que si vous devez modifier une propriété, changez-la simplement sur v, puis appelez SaveChanges (). Ne vous inquiétez pas pour définir l'état sur Modifié.

7
anon

Si vous définissez votre contexte sur AsNoTracking (), cela arrêtera aspmvc de suivre les modifications apportées à l'entité en mémoire (ce que vous souhaitez de toute façon sur le Web). N'oubliez pas la déclaration using.

using System.Data.Entity;

db.Envelopes.AsNoTracking().Find(model.ReportDate, model.Service);

Je viens de cet article du forum -> http://www.asp.net/mvc/tutorials/getting-started-with-ef-using-mvc/advanced-entity-framework-scenarios-for- une-application-web-mvc

5
David Swindells

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

var key=this.CreateEntityKey("Envelopes",model); 
        ObjectStateEntry ose;
        if(this.ObjectStateManager.TryGetObjectStateEntry(key, out ose)){
            var entity=(Page)ose.Entity;
            Envelopes.Detach(entity);
        }
            this.Envelopes.Attach(model);
3
Maslow

Et une autre approche pour résoudre le problème consiste à détacher l'entité suivie et à rattacher celle modifiée. Voir ma solution ici

0
Alexander Christov