web-dev-qa-db-fra.com

L'objet ne peut pas être supprimé car il n'a pas été trouvé dans ObjectStateManager

Je reçois cette erreur "L'objet ne peut pas être supprimé car il n'a pas été trouvé dans ObjectStateManager."

Mon code est:

    protected MyEntities sqlEntities;

    public virtual void Delete(TEntity entity)
    {
        System.Type t = typeof(TEntity);
        sqlEntities.DeleteObject(entity);
        sqlEntities.SaveChanges();
    }
103
Sami

Cela signifie que l'entité n'est pas attachée (elle n'a pas été chargée par la même instance de contexte). Essaye ça:

protected MyEntities sqlEntities;

public virtual void Delete(TEntity entity)
{
    sqlEntities.Attach(entity);
    sqlEntities.DeleteObject(entity);
    sqlEntities.SaveChanges();
}
150
Ladislav Mrnka

Juste une petite précision sur la réponse de Ladislav Mrnka (qui devrait être la réponse acceptée).

Si comme moi, vous avez un code dans un format comme celui-ci:

using (var context = new MyDataContext())
{
    context.MyTableEntity.Remove(EntytyToRemove);
    var nrOfObjectsChanged = context.SaveChanges();
}

..then ce que vous voulez faire:

using (var context = new MyDataContext())
{
    // Note: Attatch to the entity:
    context.MyTableEntity.Attach(EntityToRemove);

    context.MyTableEntity.Remove(EntityToRemove);
    var nrOfObjectsChanged = context.SaveChanges();
}

Cela semble peut-être évident, mais il n’était pas clair pour moi au début qu’il était nécessaire de spécifier le entity à attacher, et pas seulement le context

59
Kjartan

Juste pour expliquer les explications de Kjartans:

J'ai eu:

public Project DeleteProject(int id)
    {
        using (var context = new Context())
        {
            var p = GetProject(id);
            context.Projects.Remove(p);
            context.SaveChanges();
            return p;
        }
    }

Le problème est que j'ai utilisé ma propre méthode (GetProject ()) pour obtenir l'entité (d'où l'utilisation d'un autre contexte pour charger l'entité):

public Project GetProject(int id)
    {
        using (var context = new Context())
        {
            var project = context.Projects
                .Include(p => p.Reports.Select(q => q.Issues.Select(r => r.Profession)))
                .Include(p => p.Reports.Select(q => q.Issues.Select(r => r.Room)))
                .SingleOrDefault(x => x.Id == id);
            return project;      
        }
    }

Une solution pourrait consister à attacher l'entité chargée aux états de Kjartan, une autre solution pourrait être la solution de mine, pour charger l'entité dans le même contexte:

public Project DeleteProject(int id)
    {
        using (var context = new Context())
        {
            var p = context.Projects.SingleOrDefault(x => x.Id == id);
            if (p == null)
                return p;

            context.Projects.Remove(p);
            context.SaveChanges();
            return p;
        }
    }
10
esbenr

Je sais que cette question est assez ancienne, mais aucune des solutions ci-dessus n'a fonctionné pour moi car je supprimais des registres de plus d'une classe/service et chacun d'entre eux instanciait son propre contexte de connexion à une base de données.

Ce que j'ai fait pour le résoudre a été d'envoyer le premier contexte créé au reste des classes/services permettant d'accéder à la base de données.

Par exemple, ma serviceA allait supprimer certains de ses registres et appeler serviceB et serviceC pour faire de même avec leurs registres.

Je supprimerais ensuite mes registres sur serviceA et transmettrais en paramètre le contexte créé sur serviceA à serviceB et serviceC.

2
Terkhos

Vous pouvez écrire ce code:

var x=yourquery.FirstOrDefault(); 

sqlEntities.DeleteObject(x);
sqlEntities.SaveChanges();
2
mehdi

Vous devez être sûr que votre objet figure dans la liste que vous essayez de supprimer, Vous devez poser la condition suivante

if (context.entity.contains (votre objet))

retirez-le.

si vous avez une condition compliquée pour l'égalité vous devez remplacer la méthode equal dans la classe d'entité pour définir votre condition pour l'égalité, pour obtenir le bon chemin pour une méthode d'extension entity). contient "

0

J'ai ce problème et le résoudre. Il suffit de copier ci-dessous le code:

sqlEntities.Attach(entity);
sqlEntities.Remove(entity);
sqlEntities.SaveChanges();
0
vahid sabet

Assurez-vous que le modèle transmis à Remove (Entity) est exactement identique à l'enregistrement de la base de données. 

Parfois, il est possible de passer le modèle sans certains champs comme Id ou Date. conservez-les dans @ html.Hidden car si vous publiez en tant que formulaire. 

Le meilleur moyen est de transmettre l’ID et d’obtenir l’entité à l’aide de la méthode Find (Id) et de la transmettre à Remove (Entity)

J'espère que ça aide quelqu'un.

0
Dheeraj Palagiri

Si rien de ce qui précède n'a fonctionné, vous pouvez essayer cette solution:

context.Entry(yourObject).State = System.Data.Entity.EntityState.Deleted; context.SaveChanges();

0
Ala' Alnajjar