2012-04-12 21 views
13

Korzystanie z metody kodu Entity Framework.W jaki sposób usuwanie kaskadowe odbywa się w relacji jeden do wielu?

Załóżmy, że mam dwie klasy jednostki:

[Table("Objects")] 
public class DbObject : IValidatableObject 
{ 
    public long Id { get; set; } 

    public string Name { get; set; } 
    public string Description { get; set; } 

    public virtual ICollection<DbObjectProperty> Properties { get; set; } 
} 

[Table("ObjectProperties")] 
public class DbObjectProperty 
{ 
    public long Id { get; set; } 

    public string Name { get; set; } 
    public string Value { get; set; } 

    [Display(Name = "Object"), UIHint("Object")] 
    public long ObjectId { get; set; } 
    public virtual DbObject Object { get; set; } 
} 

Punkty aby pamiętać tutaj:

  • DbObject ma tylko właściwości nawigacji, ale nie kolumna z obcym kluczem
  • DbObjectProperty posiada nawigację właściwość i odpowiednia kolumna z kluczem obcym
  • I t powinno być oczywiste, że jeśli usuwam obiekt, chcę, aby jego właściwości pasowały do ​​niego, ale jeśli usunę pojedynczą właściwość, nie chcę, aby cały obiekt zniknął.

W sposobie OnModelCreating dla związku DB, aż do teraz nie miał następujący określić zależność:

modelBuilder.Entity<DbObjectProperty>() 
    .HasRequired(op => op.Object) 
    .WithMany(obj => obj.Properties) 
    .HasForeignKey(op => op.ObjectId) 
    .WillCascadeOnDelete(false); 

Oczywiście, to znaczy nie wystąpią kaskadowo Usuwa. Moje pytanie brzmi: jeśli zmienię to na true, czy zrobię to, co chcę? Pamiętaj, że jeśli usuwam obiekt, chcę, aby jego właściwości pasowały do ​​niego, ale jeśli usunę pojedynczą właściwość, nie chcę, aby cały obiekt zniknął.

Automatycznie wygenerowany kod migracja do tej zmiany (od false do true) jest taka:

DropForeignKey("ObjectProperties", "ObjectId", "Objects"); 
DropIndex("ObjectProperties", new[] { "ObjectId" }); 
AddForeignKey("ObjectProperties", "ObjectId", "Objects", "Id", cascadeDelete: true); 
CreateIndex("ObjectProperties", "ObjectId"); 

Obawiam się, że to wydaje się sugerować, że usuwając właściwość usunie powiązanych swój obiekt. Czy to będzie?

Odpowiedz

13

Kierunek Kaskadowania Usunięcie relacji w bazie danych jest zdefiniowane przez element główny (tabela klucza podstawowego/unikalnego) i jaka jest zależna (tabela klucza obcego) tej zależności.

Następnie, jeśli usuniesz główną, wszystkie osoby pozostające na utrzymaniu, które mają wartość klucza obcego odpowiadającą kluczowi podstawowemu/unikatowemu wartości klucza, są również usuwane. Nie ma kaskadowego usuwania w kierunku od zależnego od głównego.

W twoim przypadku głównym jest DbObject, a zależna to DbObjectProperty, ponieważ jest to encja/tabela z kluczem obcym.

Rzadko ma sens usuwanie kaskadowania na odwrót - szczególnie w relacjach x-do-wielu: Jeśli usuniesz zależne (DbObjectProperty), a główny (DbObject) zostanie automatycznie usunięty, klucz obcy ograniczenie byłoby naruszone, gdyby istniało inne zależne odniesienie do głównego zobowiązanego, które ma zostać usunięte.

Nie musisz się martwić.

+0

[Dziękujemy!] (Http://meta.stackexchange.com/questions/700/) – Timwi

+0

Reguła kciuka polega na tym, że przy usuwaniu kaskadowym usunięcie rekordu obcego z innego rekordu powoduje usunięcie tego zależnego rekordu także. – orad

+0

Więc 'modelBuilder.Entity () .HasMany (p => p.Children) .WithOne (c => c.Parent)' jest taki sam jak 'modelBuilder.Entity () .HasOne (c => c.Parent) .WithMany (p => p.Children) '(określają tę samą relację)? –