Cascade Delete
前言
連動刪除在兩個有關係的table之間常常會用到,例如我刪除Student資料,也要連Course資料一起刪除。
在這邊先介紹兩種連動刪除的方式
- Client-Side Cascade Delete
- Sql Cascade Delete
今天的範例關係Domain Class,Student與Course是個一對多的關係,如下:
public class Student
{
public int StudentId { get; set; }
public string Name { get; set; }
public ICollection<Course> Courses { get; set; }
}
public class Course
{
public int CourseId { get; set; }
public string Name { get; set; }
public int StudentId { get; set; }
public Student Student { get; set; }
}
Client-Side Cascade Delete
如果要讓Entity Framework做到連動刪除,則要使用eager loading,才能讓Entity Framework幫妳做到連動刪除。
var student = db.Student
.Include("Courses") //eager loading
.FirstOrDefault(x => x.Name.Equals("Miles"));
db.Student.Remove(student);
db.SaveChanges();
使用eager loading刪除的話,Entity Framework會先執行刪除Course的指令,在執行刪除Student指令,如下:
Sql Cascade Delete
基本上Client-Side Cascade Delete是給資料庫沒有支援Cascade Delete的時候方便的。 而MSSQL外部索引鍵設定,裡面可以設定刪除規則,只要將刪除規則設為重疊顯示(Cascade),則只要刪除Student,Course的資料就會自動被刪除,就不需要使用Client-Side Cascade Delete產生多個刪除指令,效能會更好。
只要把eager loading那行拿掉,Client-Side Cascade Delete的功能就會拿掉了。 拿掉後Entity Framework就只會產生一行刪除指令,此時Cascade Delete的責任就是交給資料庫處理了。
var student = db.Student
.FirstOrDefault(x => x.Name.Equals("Miles"));
db.Student.Remove(student);
db.SaveChanges();
Cascade Delete with Fluent Configuration
Cascade Delete 預設是會啟動的。 如果要拿掉Sql Cascade跟Client-Side Cascade Delete,可用WillCascadeOnDelete(false)設定。 當設定為false後,不管有沒有eager loading,刪除的時候都只會產生Delete Student的指令。
public class CourseConfiguration : EntityTypeConfiguration<Course>
{
public CourseConfiguration()
{
HasRequired<Student>(x => x.Student)
.WithMany(x => x.Courses)
.HasForeignKey<int>(x => x.StudentId)
.WillCascadeOnDelete(false);
}
}
備註:WillCascadeOnDelete()的設定也會影響到資料庫的刪除規則,如果設定false,則資料庫就不會有Cascade Delete的功能,如下圖:
注意:
只是如果把Cascade Delete拿掉的話,會變成無法單除刪除Student,因為只要該Student有Course資料的話,只要一刪除就會出現以下錯誤。 除非自行手動先刪除Course才能完整刪除資料。
一天一分享,身體好健康。
該追究的不是過去的原因,而是現在的目的。