2011-05-25 15 views
5

mam jakiś błąd: EF 4: Removing child object from collection does not delete it - why?EF 4.1: Usunięcie obiektu podrzędnego z kolekcji nie powoduje jego usunięcia - dlaczego?

kiedy wyjąć dziecko z rodzicem, że dziecko jest usunięty, gdy zgłoszę SaveChanges(), daje komunikat o błędzie następująco:

Operacja nie powiodło się: związku nie można zmienić, ponieważ jedna lub więcej właściwości klucza obcego jest nie-nullable. Gdy wprowadzana jest zmiana relacji, powiązana właściwość klucza obcego jest ustawiona na wartość pustą. Jeśli klucz obcy nie obsługuje wartości pustych, musi zostać zdefiniowana nowa relacja, właściwość klucza obcego musi mieć przypisaną inną wartość inną niż null lub obiekt niepowiązany musi zostać usunięty.

Ale z DbContext i EF 4.1, "context.DeleteObject (przepis)" nie istnieje.

Jakieś sugestie?

[EDIT]

public void UpdateWithAttributes(Model model, IEnumerable<Entity> entities) 
    { 
     var modelOriginal = this.unitOfWork.Model.GetById(model.IModel); 

     this.unitOfWork.Context.Entry(modelOriginal).CurrentValues.SetValues(model); 
     UpdateEntityAttributeAssociations(modelOriginal, entities); 

     this.unitOfWork.Commit(); 
    } 

    public void UpdateEntityAttributeAssociations(Model model, IEnumerable<Entity> current) 
    { 
     unitOfWork.Context.Entry(model).Collection(m => m.Entities).Load(); 
ICollection<Entity> original = model.Entities; // perhaps .ToList() necessary 

     // delete 
     if (original != null) 
     { 
      List<Entity> toDelete = GetToDelete(original, current); 

      foreach (Entity originalEntityToDelete in toDelete) 
      { 
       unitOfWork.Context.Entity.Remove(originalEntityToDelete); 
      } 
     } 

     // add, update 
     if (current != null) 
     { 
      foreach (Entity currentEntity in current) 
      { 
       // No need to set the UpdatedWhen. The trigger on the table will handle that. 
       if (original.Where(originalEntity => originalEntity.IEntity == currentEntity.IEntity).FirstOrDefault() == null) 
       { 
        model.Entities.Add(currentEntity); 
       } 
      } 
     } 
    } 

Odpowiedz

1

Chyba, że ​​jesteś dodając jeszcze to, co przed chwilą usunięty, ponieważ usunięcie z DbSet także usuwa wewnętrznie podmiot z kolekcji dziecięcej original. Następnie w drugiej pętli ponownie dodajemy obiekt. Można spróbować złapać tę sytuację tak:

public void UpdateEntityAttributeAssociations(Model model, 
               IEnumerable<Entity> current) 
{ 
    unitOfWork.Context.Entry(model).Collection(m => m.Entities).Load(); 
    ICollection<Entity> original = model.Entities; // perhaps .ToList() necessary 

    // delete 
    List<Entity> toDelete = null; 
    if (original != null) 
    { 
     toDelete = GetToDelete(original, current); 
     foreach (Entity originalEntityToDelete in toDelete) 
     { 
      unitOfWork.Context.Entity.Remove(originalEntityToDelete); 
     } 
    } 

    // add, update 
    if (current != null) 
    { 
     foreach (Entity currentEntity in current) 
     { 
      if (toDelete == null || !toDelete.Contains(currentEntity)) 
      { 
       if (original.Where(originalEntity => originalEntity.IEntity == 
           currentEntity.IEntity).FirstOrDefault() == null) 
       { 
        model.Entity.Add(currentEntity); 
       } 
      } 
     } 
    } 
} 

jakie otrzymuje również swój pierwszy wiersz z wyraźną załadunku kolekcję dziecięcą Ponieważ procedura kwerendy podmioty podrzędne ręcznie wygląda znają mnie, ale ja nie myślę, że to jest problem (ale nie wiem).

Edit

Nie jestem pewien, czy mój kod powyżej pomaga usunąć wyjątek miałeś. Nie wiem, co się stanie, jeśli dodasz jednostkę do kolekcji, która jest już w stanie Deleted i jeśli to może spowodować ten wyjątek.

Jeżeli kod nie pomaga można sprawdzić, czy masz również problem bez sekundę (Insert) pętli. A jak dokładnie wygląda GetToDelete? A jak wyglądają twoje klasy i ich relacje w klasie Model i Entity? I czy jest to inna kolekcja niż model.Entity (czy jest to literówka)?

+0

Dziękuję Slauma za odpowiedź .Z twoim kodem mam kolejny błąd: Instrukcja DELETE jest w konflikcie z ograniczeniem REFERENCE {0} Konflikt wystąpił w bazie danych \ "MyDatabase \", tabela \ "{1} \", kolumna „{2}” \ r ​​stwierdzenie \ nIm zostało zakończone – rad

+0

@rad:.. nie mam pojęcia, należy edytować odpowiedzi na moje ostatnie pytania powyżej do Twojego pytania..Jest zbyt wiele brakujących informacji, aby szczegółowo zrozumieć problem i zapewnić działające rozwiązanie (przynajmniej dla mnie). – Slauma

+0

@rad: Myślę, że istnieje inny byt, który odnosi się do istoty, którą właśnie próbujesz usunąć. Sekretna zawartość '{0}', '{1}' i '{2}' powinna dać raczej ważną wskazówkę! – Slauma

2

Trzeba zadzwonić:

context.Recipes.Remove(recipe); 

Gdzie RecipesDbSet<Recipe>.

+0

próbowałem, ale mam wciąż ten sam błąd :( – rad

+0

Zaktualizuj swoje pytanie z próbki kodu. –

+0

Jest aktualizowana, dzięki – rad

Powiązane problemy