Cascade delete automatically deletes dependent records or sets null to ForeignKey columns when the parent record is deleted in the database.
Cascade delete is enabled by default in Entity Framework for all types of relationships such as one-to-one, one-to-many and many-to-many.
Consider the following Student
and StudentAddress
entities that have a one-to-zero-or-one relationship.
public class Student { public int StudentId { get; set; } public string StudentName { get; set; } public virtual StudentAddress Address { get; set; } } public class StudentAddress { [ForeignKey("Student")] public int StudentAddressId { get; set; } public string Address1 { get; set; } public string Address2 { get; set; } public string City { get; set; } public int Zipcode { get; set; } public string State { get; set; } public string Country { get; set; } public virtual Student Student { get; set; } }
The following example demonstrates the cascade delete operation.
using (var ctx = new SchoolContext()) { var stud = new Student() { StudentName = "James" }; var add = new StudentAddress() { Address1 = "address" }; stud.Address = add; ctx.Students.Add(stud); ctx.SaveChanges(); ctx.Students.Remove(stud);// student and its address will be removed from db ctx.SaveChanges(); }
In the above example, first EF saves stud
and its StudentAddress
entity to the database and then, when it removes stud
and calls SaveChanges()
, EF will delete stud
as well as its corresponding record in the StudentAddresses
table.
Thus, EF enables cascade delete by default.
Consider the following Student
and Standard
entities that have a one-to-many relationship.
public class Student { public int StudentId { get; set; } public string StudentName { get; set; } public virtual Standard Standard { get; set; } } public class Standard { public Standard() { Students = new List<Student>(); } public int StandardId { get; set; } public string Description { get; set; } public virtual ICollection<Student> Students { get; set; } }
The following example demonstrates the cascade delete effect between entities that have a one-to-many relationship.
using (var ctx = new SchoolContext()) { var student1 = new Student() { StudentName = "James" }; var student2 = new Student() { StudentName = "Gandhi" }; var standard1 = new Standard() { StandardName = "Standard 1" }; student1.Standard = standard1; student2.Standard = standard1; ctx.Students.Add(student1); ctx.Students.Add(student2); //inserts students and standard1 into db ctx.SaveChanges(); //deletes standard1 from db and also set standard_StandardId FK column in Students table to null for // all the students that reference standard1. ctx.Standards.Remove(standard1); ctx.SaveChanges(); }
In the above example, EF deletes standard1
from the database and also sets standard_StandardId
FK column in the Students
table to null for all the records that reference standard1
.
Note: EF automatically deletes related records in the middle table for many-to-many relationship entities if one or the other entity is deleted.
Thus, EF enables the cascading delete effect by default for all the entities.
Use Fluent API to configure entities to turn off cascade delete using the WillCascadeOnDelete()
method, as shown below.
public class SchoolContext<: DbContext { public SchoolContext():base("MySchool") { } public DbSet<Student> Students { get; set; } public DbSet<Standard> Standards { get; set; } protected override void OnModelCreating(DbModelBuilder modelBuilder) { modelBuilder.Entity<Student>() .HasOptional<Standard>(s => s.Standard) .WithMany() .WillCascadeOnDelete(false); } }
Note: No data annotation attribute is available to turn off cascade delete.