2009-08-01 18 views
14

Ich bekomme "Das Objekt kann nicht gelöscht werden, weil es nicht im ObjectStateManager gefunden wurde". während Löschen eines Objekts.Entity Framework Objekt löschen Problem

Hier sind 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(); 


      }} 

Antwort

28

Sie müssen das Objekt an die ObjectContextattach. Versuchen:

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

angebaute Objekte durch die ObjectContext verfolgt werden. Dies wird benötigt, um Löschungen und Aktualisierungen durchzuführen. Sie können mehr über attaching objects auf MSDN lesen.

bearbeiten klären Anbringen/Abnehmen:

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 
    } 
} 

Außerdem sollten Sie Ihre Verwendung von ObjectContext s in using Blöcke wickeln.

+0

ich bekomme diesen Fehler jetzt; Ein Entitätsobjekt kann nicht von mehreren Instanzen von IEntityChangeTracker referenziert werden. –

+0

Sie müssen es aus dem ObjectContext lösen, von dem Sie die Entität erhalten haben. Rufen Sie ObjectContext.Detach mit dem Objekt als Parameter auf. – jason

+0

jetzt bin ich Fehler wie "Objekt kann nicht losgelöst, weil es nicht atached". :( –

5

In Ihrer Methode „Form1_Load“ Sie eine erste Instanz des „FirebirdEntity“ Kontextes erstellen eine die ListViewItem mit Einheiten aus diesem Zusammenhang

In Ihrer Methode „button3_Click“ erstellen Sie eine neue, zweite Instanz des ausgewählten füllen "FirebirdEntity" -Kontext. Dann versuchen Sie, eine Entität in diesem zweiten Kontext zu löschen, der im ersten Kontext ausgewählt wurde.

Verwenden Sie die gleiche Instanz Ihres Kontextes in beiden Methoden und alles wird gut funktionieren.

(Alternativ können Sie die Einheit wählen Sie eine von Ihrem zweiten Kontext löschen möchten, und dann diese Einheit löschen, anstatt den Ursprung eins)

2

in der Regel für ein Löschen in der Datenbank i diese Art von Linq-Abfrage verwenden, immer funktioniert, es sei denn, Sie haben eine Fremdschlüssel-Rückhaltesicherung:

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(); 

Ich hoffe, dies hilft.

3

Ich führte eine Linq-Abfrage innerhalb meiner DomainService-Methoden und löschte dann aus dem Ergebnis, so während der erste Ausschnitt unten mit Fehler fehlschlug "Das Objekt kann nicht gelöscht werden, weil es nicht im ObjectStateManager gefunden wurde", funktionierte der zweite Ausschnitt.

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

Das funktionierte:

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); 
} 
2

Angenommen, ich habe ein Objekt namens Department, mit einem Surrogatschlüssel DepartmentUUID

DDL sieht wie folgt aus:

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 

Jetzt für das Entity Framework Code. Die wichtigen Teile sind: 1. Verwenden Sie die AttachTo-Methode. 2. Erstellen eines temporären Objekts und Festlegen des Primärschlüsselwerts. (Ersatzschlüssel).

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; 

} 
+2

Die letzten 4 Zeilen sollten genau das sein: return context.SaveChanges() ;. Auch returnValue-Variable entfernen. Warum erstellen Sie so viel unnützes Rauschen im Code? –

+0

Einige Frameworks geben das Objekt zurück, das entfernt wurde. (Http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html#remove())) Einige Frameworks geben einen bool zurück, wenn die Methode funktioniert Einige Frameworks geben die Anzahl der betroffenen Zeilen zurück Einige Frameworks geben void zurück Nur weil Sie es nicht tun würden, bedeutet das nicht, dass es keinen legitimen Bedarf für i gibt t. Aber ja, mein Code könnte mit "returnValue = context.SaveChanges();" abgespeckt werden. (<< Nur um zu zeigen, dass ich nicht unbarmherzig bin.) Ja, wenn Sie sich dafür entscheiden, könnten Sie etwas mehr Code entfernen. Manchmal wird Lesbarkeit gegenüber Prägnanz bevorzugt. – granadaCoder

+0

Ja, Lesbarkeit. Dieser Code ist so hässlich wie möglich. Und nicht lesbar. Das ist es was ich meinte. –

1

Die disgustingly schreckliche Hack, den ich ist benutzten:

var attachedObject = _repository.GetObjectByKey(detachedObject.EntityKey); 

Werke für viele dieser Probleme. Ich hatte gehofft, eine elegantere Lösung für dieses Problem zu finden, indem ich hierher komme. Dies scheint den Trick zu machen.

Verwandte Themen