欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

15.翻译系列:EF 6中的级联删除【EF 6 Code-First 系列】

程序员文章站 2022-03-13 17:53:20
原文链接:https://www.entityframeworktutorial.net/code-first/cascade-delete-in-code-first.aspx EF 6 Code-First系列文章目录: 1 翻译系列:什么是Code First(EF 6 Code First ......

原文链接:

 

ef 6 code-first系列文章目录:

 

 

当数据库的父记录被删除的时候,级联删除自动的删除相关的依赖记录,或者设置外键列为null。

ef 对于一对一,一对多,多对多关系,默认是启用了级联删除。

 

一对一关系中的级联删除

 

下面的student和studentaddress实体,是一对零或一的关系。

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

下面的操作,演示了级联删除。

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

在上面的代码中,首先,ef保存stud和其studentaddress实体到数据库中,然后删除stud,调用savechanges().ef就会删除stud,并且将studentaddress表中相关级联一并删除。所以,ef默认是级联删除的。

 

一对多关系中的级联删除

 

下面的student和standard实体,是一对多关系。

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

下面的代码,演示了一对多关系中的级联删除。

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

在上面的例子中,ef从数据库中删除了standard1,并且设置students表中的相关联的standard_standardid外键列为null。

请注意:对于多对多关系,如果两个实体中的任何一个删除了,ef自动的删除中间表中相关的记录。

所以,ef默认是对所有的实体【一对一的中的实体、一对多中的实体、多对多中的实体】启用了级联删除。

 

关闭级联删除

 

可以用fluent api中的willcascadeondelete()来处理级联删除,例如:

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

 

请注意:没有数据注解的特性,可以用来关闭级联删除。