简体   繁体   English

实体框架外键约束

[英]Entity framework foreign key constraint

I'm still getting my head around using EF. 我仍然在使用EF。 I using a code first approach in my project and stumbled upon the following issue. 我在我的项目中使用代码优先方法并偶然发现了以下问题。

I have the following objects: 我有以下对象:

public class Employee
{
    public int EmployeeId { get; set; }
    public int BusinessUnitId { get; set; }

    public virtual BusinessUnit BusinessUnit { get; set; }
}

public class Quote
{
    public int QuoteId { get; set; }

    [DisplayName("Business Unit")]
    public int BusinessUnitId { get; set; }

    [DisplayName("Responsible Employee")]
    public int EmployeeId { get; set; }

    [DisplayName("Date Issued")]
    [DataType(DataType.Date)]
    public DateTime DateIssued { get; set; }

    [DataType(DataType.MultilineText)]
    public string Description { get; set; }

    public virtual Employee Employee { get; set; }
    public virtual BusinessUnit BusinessUnit { get; set; }
}

Both include a BusinessUnit property, and it seems that EF doesn't want to allow this. 两者都包含BusinessUnit属性,似乎EF不想允许这样做。 Seeing that I get the following error below on the Index() method when a Linq query with a bunch of includes are executed. 当执行带有一堆包含的Linq查询时,看到我在Index()方法下面得到以下错误。

Introducing FOREIGN KEY constraint 'FK_dbo.Quotes_dbo.BusinessUnits_BusinessUnitId' on table 'Quotes' may cause cycles or multiple cascade paths. 在表'Quotes'上引入FOREIGN KEY约束'FK_dbo.Quotes_dbo.BusinessUnits_BusinessUnitId'可能会导致循环或多个级联路径。 Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints. 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束。 Could not create constraint. 无法创建约束。 See previous errors. 查看以前的错误。

Can someone please explain to me why I get this error and how I might go about fixing it. 有人可以向我解释为什么我会收到这个错误,以及我如何解决它。 Thanks. 谢谢。

EDIT: 编辑:

This is definitly caused by including the BusinessUnit property in both the Quote object and the Employee object. 这绝对是由于在Quote对象和Employee对象中都包含BusinessUnit属性。 I just dont understand why. 我只是不明白为什么。

EDIT 2: 编辑2:

The code for the BusinessUnit class: BusinessUnit类的代码:

public class BusinessUnit
{
    public int BusinessUnitId { get; set; }
    public string Name { get; set; }
}

Right now, if you try to delete an Employee, it will attempt to delete the Quote, the BusinessUnit for that Quote, and then the Employees for that BusinessUnit, etc. 现在,如果您尝试删除Employee,它将尝试删除Quote,该Quote的BusinessUnit,然后删除该BusinessUnit的Employees等。

Either make some relationships optional, or turn off cascading conventions as below: 要么使某些关系可选,要么关闭级联约定,如下所示:

protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
    // Either entirely
    modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

    // or for one model object
    modelBuilder.Entity<Person>()
       .HasRequired(p => p.Department)
       .WithMany()
       .HasForeignKey(p => p.DepartmentId)
       .WillCascadeOnDelete(false);
}

Adding comment as answer: It's a conflict between the BusinessUnitId properties and the BusinessUnit properties 添加注释作为答案:这是BusinessUnitId属性和BusinessUnit属性之间的冲突

Remove the BusinessUnitId property from Quote and Employee classes 从Quote和Employee类中删除BusinessUnitId属性

At the core of this issue is SQL Server's refusal to allow circular referenced cascading deletes (as the SO link from @Oskar discusses). 这个问题的核心是SQL Server拒绝允许循环引用的级联删除(正如@Oskar讨论的SO链接)。 EF is relaying an exception from SQL Server to you. EF正在将SQL Server的异常转发给您。 It is being triggered by code first's default behavior: " If a foreign key on the dependent entity is not nullable, then Code First sets cascade delete on the relationship. If a foreign key on the dependent entity is nullable, Code First does not set cascade delete on the relationship, and when the principal is deleted the foreign key will be set to null. " 它由代码优先的默认行为触发:“ 如果依赖实体上的外键不可为空,则Code First会在关系上设置级联删除。如果依赖实体上的外键可以为空,则Code First不会设置级联删除关系,当删除主体时,外键将被设置为null。

You should be able to overcome this issue by making at least one of your BusinessUnitId properties nullable, either on Quote or Employee. 您应该能够通过在Quote或Employee上使至少一个BusinessUnitId属性可以为空来克服这个问题。 Alternatively, you can use EF's fluent api to specify cascade delete rules. 或者,您可以使用EF的流畅api指定级联删除规则。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM