【译】第29节---级联删除

原文:http://www.entityframeworktutorial.net/code-first/cascade-delete-in-code-first.aspx

当删除主记录时,级联删除会自动删除相关记录,或将外键属性设置为空值。

默认情况下,EF对所有类型的关系(一对一、一对多和多对多)启用级联删除。

一对一关系中的级联删除

看以下具有一对一关系的Student和StudentAddress实体:

public class Student
{
    public 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; }
}

以下示例演示了删除学生时的级联删除操作:

using (var ctx = new SchoolContext()) {

    var student1 = new Student() { StudentName = "James" };
    var address1 = new StudentAddress() { Address1 = "address" };

    student1.Address = address1;

    ctx.Students.Add(student1);

    ctx.SaveChanges();
    // student1 and its address will be removed from db
    ctx.Students.Remove(student1);

    ctx.SaveChanges();
}

上面的例子中,首先将Student和studentAddress保存到数据库中,然后当删除student1并调用SaveChanges()时,EF将从数据库中删除student1及其StudentAddress。

因此,默认情况下,EF启用级联删除。

一对多关系中的级联删除

看以下具有一对多关系的Student和Standard实体:

public class Student
{
    public 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; }
}

以下示例演示了具有一对多关系的实体之间的级联删除操作:

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();
}

上面的例子中,从db中删除了standard1,并且将引用standard1的所有记录中,将Students表中的standard_StandardId FK列设置为null。

当多对多关系的中间表中的其中一个实体被删除,EF将自动删除关联的记录。

因此,EF为所有实体默认启用级联删除效果。

关闭级联删除

使用Fluent API配置实体关闭级联删除,如下所示:

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);
    }
}

注意:DataAnnotations不包括任何关闭级联删除的属性。

原文地址:https://www.cnblogs.com/talentzemin/p/7299582.html