2013-07-25 20 views
22

Gdy próbuję usunąć kolekcję (wzywającą .Clear) pojawia się następujący wyjątek:związek jest w usuniętej stanie

Wystąpił błąd podczas zapisywania podmioty, które nie narażają zagranicznych kluczowych właściwości ich relacji . Właściwość EntityEntries zwróci wartość null, ponieważ nie można zidentyfikować pojedynczej encji jako źródła wyjątku. Obsługa wyjątków podczas zapisywania może być łatwiejsza dzięki ujawnieniu właściwości klucza obcego w typach jednostek. Zobacz szczegóły wyjątku InnerException.

Wewnętrzna wyjątek:

Związek z określenia 'User_Availability' AssociationSet znajduje się w stanie 'usunięte'. Biorąc pod uwagę ograniczenia wielokrotności, odpowiedni "User_Availability_Target" musi również znajdować się w stanie "Usunięte".

Użytkownik wygląda następująco:

.... 
ICollection<Availability> Availability { get; set; } 

Dostępność wygląda następująco:

int ID { get; set; } 
User User { get; set; } 
DateTime Start { get; set; 
DateTime End { get; set; } 

Konfiguracja jest następująca:

HasMany(x => x.Availability).WithRequired(x => x.User); 
HasRequired(x => x.User).WithMany(x => x.Availability); 

Kod przyczyną problemu jest:

user.Availability.Clear(); 

Przyjrzałem się innym alternatywom, takim jak użycie DbSet do usuwania elementów, ale nie uważam, że mój kod będzie tak czysty. Czy istnieje sposób, aby to osiągnąć, usuwając kolekcję?

Odpowiedz

22

Jedynym sposobem, o którym wiem, że działa, jest określenie związku jako identifying relationship. To wymaga wprowadzenia klucza obcego z Availability do User jako klucz obcy do modelu ...

public int ID { get; set; } 
public int UserID { get; set; } 
public User User { get; set; } 

... i uczynić go częścią klucza podstawowego:

modelBuilder.Entity<User>() 
    .HasKey(u => new { u.ID, u.UserID }); 

Można rozszerz swoje odwzorowanie w celu włączenia tego klucza obcego (żeby być wyraźny, nie jest wymagane, ponieważ EF rozpozna go umownie):

modelBuilder.Entity<User>() 
    .HasRequired(x => x.User) 
    .WithMany(x => x.Availability) 
    .HasForeignKey(x => x.UserID); 

(BTW: trzeba config relacja tylko z jednej strony. Nie jest wymagane posiadanie obu tych mapowań w pytaniu.)

Teraz możesz wyczyścić kolekcję przy pomocy user.Availability.Clear();, a jednostki Availability zostaną usunięte z bazy danych.

+1

Dzięki Slauma, rozwiązałem mój problem. – Sam

+0

Dzięki za zamieszczenie tego! Po uruchomieniu aktualizacji obiektu podrzędnego otrzymuję wiele instrukcji SET w tej samej kolumnie, ze względu na właściwość FK i właściwość nawigacji. Czy istnieje sztuczka, która generuje tylko jedną instrukcję SET? – Thomas

+0

@Thomas: Nie mam pojęcia. Generowanie kodu SQL jest praktycznie w rękach EF i trudne do kontrolowania. Jestem naprawdę zaskoczony, że otrzymujesz dwa wyrażenia SET dla tej samej kolumny FK. EF powinien wiedzieć, że właściwość FK i nav. Właściwość reprezentuje tę samą kolumnę FK i relację. – Slauma

0

Jest jedna sztuczka. Można usuwać jednostki bez użycia specjalnego narzędzia DbSet:

(this.dataContext as IObjectContextAdapter).ObjectContext.DeleteObject(entity); 

Wykonaj tę operację dla każdej pozycji w kolekcji Dostępność przed jej wyczyszczeniem. W ten sposób nie potrzebujesz "identyfikacji związków".

Powiązane problemy