14 votes

Problème de suppression d'objet dans Entity Framework

J'obtiens "L'objet ne peut être supprimé car il n'a pas été trouvé dans l'ObjectStateManager". pendant la suppression de l'objet.

Voici les codes ;

//first i am filling listview control.
 private void Form1_Load(object sender, EventArgs e)
    {
        FirebirdEntity asa = new FirebirdEntity();

        ObjectQuery<NEW_TABLE> sorgu = asa.NEW_TABLE;

        foreach (var item in sorgu)
        {
            ListViewItem list = new ListViewItem();
            list.Text = item.AD;
            list.SubItems.Add(item.SOYAD);
            list.Tag = item;
            listView1.Items.Add(list);

        }
//than getting New_table entity from listview's tag property.
 private void button3_Click(object sender, EventArgs e)
    {

            using (FirebirdEntity arama = new FirebirdEntity())
            {

               NEW_TABLE del = (NEW_TABLE)listView1.SelectedItems[0].Tag;
               arama.DeleteObject(del);
               arama.SaveChanges();

            }}

28voto

Jason Points 125291

Vous devez joindre l'objet au ObjectContext . Essayez :

NEW_TABLE del = (NEW_TABLE)listView1.SelectedItems[0].Tag;
arama.Attach(del);
arama.DeleteObject(del);
arama.SaveChanges();

Les objets attachés sont suivis par le ObjectContext . Ceci est nécessaire pour effectuer des suppressions et des mises à jour. Vous pouvez en savoir plus sur attacher des objets sur MSDN.

Editer pour clarifier attacher/détacher :

private void Form1_Load(object sender, EventArgs e) {
    FirebirdEntity asa = new FirebirdEntity();

    ObjectQuery<NEW_TABLE> sorgu = asa.NEW_TABLE;
    foreach (var item in sorgu) {
        asa.Detach(item);
        // add to listView1
    }
}

De plus, vous devez envelopper votre utilisation de ObjectContext en using blocs.

5voto

Chrigl Points 123

Dans votre méthode "Form1_Load", vous créez une PREMIÈRE instance de votre contexte "FirebirdEntity" et remplissez le ListViewItem avec les entités sélectionnées dans ce contexte.

Dans votre méthode "button3_Click" vous créez une NOUVELLE, SECONDE instance de votre contexte "FirebirdEntity". Ensuite, vous essayez de supprimer une entité dans ce SECOND contexte, qui a été sélectionnée dans le PREMIER contexte.

Utilisez la même instance de votre contexte dans vos deux méthodes et tout fonctionnera bien.

(Vous pouvez également sélectionner l'entité que vous souhaitez supprimer dans votre SECOND contexte, puis supprimer cette entité au lieu de celle d'origine).

3voto

Scott Moore Points 21

J'ai exécuté une requête linq dans les méthodes de mon DomainService et j'ai ensuite supprimé le résultat. Ainsi, alors que le premier extrait ci-dessous a échoué avec l'erreur "L'objet ne peut être supprimé car il n'a pas été trouvé dans l'ObjectStateManager", le deuxième extrait a fonctionné.

public void DeleteSharedDoc(SharedDocs shareddoc)
{
       this.ObjectContext.SharedDocs.DeleteObject(shareddoc);
}

Ça a marché :

public void DeleteSharedDoc(SharedDocs shareddoc)
{
var query = (from w in this.ObjectContext.SharedDocs
            where w.UserShareName == shareddoc.UserShareName
            && w.UserShareUsersEmail == shareddoc.UserShareUsersEmail
            && w.DocumentId == shareddoc.DocumentId
            select w).First();
this.ObjectContext.SharedDocs.DeleteObject(query);
}

2voto

Daniel Casserly Points 23

Habituellement, pour une suppression dans une base de données, j'utilise cette sorte de requête linq, qui fonctionne toujours, sauf si vous avez une contrainte de clé étrangère :

int id = convert.toint32(some text field from the page);
entity data = new entity();
var del = (from record in data.records 
          where record.id == id
          select record).FirstOrDefault();
data.deleteObject(del);
data.saveChanges();

J'espère que cela vous aidera.

2voto

granadaCoder Points 6390

Supposons que j'ai un objet appelé Département, avec une clé de substitution DepartmentUUID.

Le DDL ressemble à ceci :

CREATE TABLE [dbo].[Department] 
    ( 
          DepartmentUUID [UNIQUEIDENTIFIER] NOT NULL 
        , DepartmentName varchar(24) not null
        , CreateDate smalldatetime not null 
    )
GO

ALTER TABLE [dbo].[Department] ADD CONSTRAINT PK_Department PRIMARY KEY NONCLUSTERED (DepartmentUUID) 
GO

ALTER TABLE [dbo].[Department] ADD CONSTRAINT CK_DepartmentName_Unique UNIQUE (DepartmentName) 
GO

ALTER TABLE [dbo].[Department] ADD CONSTRAINT [DF_Department_DepartmentUUID] DEFAULT ( NEWSEQUENTIALID() ) FOR DepartmentUUID
GO

ALTER TABLE [dbo].[Department] ADD CONSTRAINT [DF_Department_CreateDate] DEFAULT ( CURRENT_TIMESTAMP ) FOR CreateDate
GO

Maintenant pour le code Entity Framework. Les parties importantes sont : 1. Utilisation de la méthode AttachTo. 2. Création d'un objet temporaire, et définition de la valeur primary-key de celui-ci. (clé de substitution).

public int DeleteDepartment(Guid departmentUUID)
{

    int returnValue = 0;

    Department holder = new Department();
    holder.DepartmentUUID = departmentUUID; // DepartmentUUID is the primary key of this object (entity in the db)

    using (MyContectObject context = new MyContectObject())
    {
        context.AttachTo("Departments", holder);

        context.DeleteObject(holder);

        int numOfObjectsAffected = context.SaveChanges();
        returnValue = numOfObjectsAffected;

        context.Dispose();
    }

    return returnValue;

}

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X