如何设置导航属性以强制删除相关记录

时间:2014-12-17 15:12:10

标签: c# asp.net-mvc entity-framework model-view-controller relationship

我正在使用MVC 4和VS2010与Entity Framework 6.1.x.我正在使用Code First相当简单的数据库,但它有一个稍微复杂一点的部分。首先,两个表PersonRecording具有1对多的关系。

public class Person {
    public int PersonID { get; set; }
    public int GenderID { get; set; }

    // Navigation property
    public virtual List<Recording> Recordings { get; set; }
}

public class Recording {
    public int RecordingID { get; set; }
    // ...
    public int PersonID { get; set; }

    // Navigation properties
    public virtual Person Person { get; set; }
    public virtual List<Junction> Junctions { get; set; }
}

默认情况下,当我删除Person时,实体框架会删除与Person相关的所有录制内容。这就是我的期望。但是来自Recording表的记录也放在不同的表集中。假设我有一个名为ApplicantApplicationJunction的表格。当我通过删除PersonRecording删除任何录制内容时,我希望删除Junction中与Recording中的记录相关的所有记录。在我的项目中,如果与特定应用程序相关的记录数量为零,则没有意义。

合并Primary KeyApplicantIDApplicationIDRecordID Junction组成了复合键。

是否可以通过Entity Framework强制执行约束,或者我宁愿提供自己的自定义函数?

如何在相应的表中设置导航属性:RecordingJunction以便删除相关的录音?

public class Applicant
{
    public int ApplicantID { get; set; }
    // Navigation property
    public virtual List<Junction> Junctions { get; set; }
}

public class Application {
    public int ApplicationID { get; set; }

    // Navigation property
    public virtual List<Junction> Junctions { get; set; }
}    

public class Junction
{
    public int ApplicationID { get; set; }
    public int ApplicantID { get; set; }
    public int RecordingID { get; set; }

    public virtual Application Application { get; set; }
    public virtual Applicant Applicant { get; set; }
    public virtual Recording Recording { get; set; }
}

感谢您的帮助。


<小时/> EDIT

@克里斯。根据我的理解,如果外键不可为空,如果删除主表中具有相应PrimaryID的记录,则删除辅助表中的记录。另一方面,如果外键可以为空,则辅助表中的记录将变为null但不会被删除。

我制作了这个项目和两个表,我填充了数据库。在课程Student中,如果我让DepartmentID不可为空,

public int DepartmentID { get; set; }
删除包含主DepartmentID的记录时,将删除

记录。这是我的期望,但如果我使DepartmentID可以为空

public int? DepartmentID { get; set; }

然后我收到了这个错误:

  

DELETE语句与REFERENCE约束“FK_dbo.Student_dbo.Department_DepartmentID”冲突。冲突发生在数据库“TestDB”,表“dbo.Student”,列'DepartmentID'中   该声明已被终止。

在测试项目中,我创建了两个表,关系为1到多个。

public class Department
{
    public int DepartmentID { get; set; }
    public string DepartmentName { get; set; }

    public virtual List<Student> Students { get; set; }
}

public partial class Student : IDisposable
{
    public int StudentID { get; set; }
    public int DepartmentID { get; set; }

    public virtual Department Department { get; set; }
}

这是我应该期待的吗?

1 个答案:

答案 0 :(得分:1)

删除级联不是为了随意删除项目。它存在于必要之中。在上面的示例中,Recording具有Person的不可为空的外键。如果删除了Person,则必须将外键设置为null(这不会发生)或必须删除所有相关的Recording以保留参照完整性。

在使用Junction的第二个示例中,Record是一个不可为空的外键。因此,如果您删除Person所有相关的Record,则应删除与这些记录相关的所有Junction。但是,如果删除Junction,则不会采取进一步操作。没有什么本质上依赖于Junction,因此它的删除不被注意。它曾引用的任何Record仍然有效。请记住,这完全是为了保持参照完整性。只要完整性完好无损,就不会删除任何东西。