2009-08-01 14 views
14

Otrzymuję "Obiekt nie może zostać usunięty, ponieważ nie został znaleziony w ObjectStateManager". podczas usuwania obiektu.Entity Framework Delete Object Problem

tutaj są kody;

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


      }} 

Odpowiedz

28

Trzeba attach obiekt do ObjectContext. Wypróbuj:

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

Dołączone obiekty są śledzone przez ObjectContext. Jest to potrzebne do usuwania i aktualizacji. Możesz przeczytać więcej o attaching objects na MSDN.

Edit wyjaśnienie dołączyć/odłączyć:

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

Ponadto, należy owinąć wykorzystanie ObjectContext sw using bloków.

+0

Otrzymuję teraz ten błąd; Nie można odwoływać się do obiektu encji przez wiele instancji IEntityChangeTracker. –

+0

Musisz odłączyć go od ObjectContext, który dostarczył ci obiekt. Wywołanie ObjectContext.Detach z obiektem jako parametrem. – jason

+0

Teraz jestem błąd Gettin jak "obiekt nie można odłączyć, ponieważ nie jest on atached". :( –

5

W swojej metodzie „Form1_Load” utworzeniu pierwszej instancji swojego „FirebirdEntity” context wypełnić ListViewItem z podmiotami wybranymi z tym kontekście

W swojej metodzie „button3_Click” utworzeniu nowej, drugiej instancji twoich Kontekst "FirebirdEntity". Następnie próbujesz usunąć encję w tym kontekście SECOND, który został wybrany w kontekście FIRST.

Użyj tej samej instancji kontekstu w obu metodach i wszystko będzie działać poprawnie.

(Alternatywnie można wybrać podmiot, który chcesz usunąć z drugim kontekście, a następnie usunąć ten podmiot, a nie pochodzenia jeden)

2

zwykle DELETE w bazie Używam tego rodzaju kwerendy LINQ, zawsze działa, dopóki nie masz klucza obcojęzycznego:

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

Mam nadzieję, że to pomoże.

3

Uruchomiłem kwerendę linq w moich metodach DomainService, a następnie usunięto z wyniku, więc podczas gdy pierwszy opis poniżej nie powiódł się z błędem "Obiekt nie może zostać usunięty, ponieważ nie został znaleziony w ObjectStateManager", działał drugi fragment.

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

To działało:

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

Załóżmy mam obiektu o nazwie Zakład, z surrogatekey DepartmentUUID

DDL wygląda następująco:

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 

Teraz Entity Framework kod. Ważne części to: 1. Korzystanie z metody AttachTo. 2. Tworzenie tymczasowego obiektu i ustawianie jego wartości kluczem podstawowym. (Klucz zastępczy).

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

Ostatnie 4 wiersze powinny być właśnie tym: return context.SaveChanges() ;. Usuń również zmienną returnValue. Po co tworzyć tyle bezużytecznego szumu w kodzie? –

+0

Niektóre frameworki zwracają obiekt, który został usunięty. (Http://docs.oracle.com/javase/6/docs/api/java/util/ArrayList.html#remove(int)) Niektóre frameworki zwracają wartość bool, jeśli metoda zadziałała, niektóre frameworki zwracają liczbę wierszy, których to dotyczy, Niektóre frameworki zwracają nieważność. Tylko dlatego, że tego nie zrobiłeś, nie oznacza to, że nie ma uzasadnionej potrzeby. t. Ale tak, mój kod może zostać odchudzony przez użycie "returnValue = context.SaveChanges();". (<< Tylko po to, aby pokazać, że nie jestem nieosiągalny.) Tak, jeśli wybierzesz, możesz usunąć więcej kodu. Czasami lepsza jest czytelność niż zwięzłość. – granadaCoder

+0

Tak, czytelność. Ten kod jest tak brzydki jak to tylko możliwe. I nieczytelne. O to mi chodziło. –

1

obrzydliwie straszne Hack użyłem to:

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

pracuje dla wielu z tych problemów. Miałem nadzieję znaleźć bardziej eleganckie rozwiązanie tego problemu, przychodząc tutaj. Wydaje się, że to wystarczy.