实体框架外键约束

时间:2013-05-23 13:40:09

标签: c# asp.net-mvc entity-framework

我仍然在使用EF。我在我的项目中使用了代码优先方法,偶然发现了以下问题。

我有以下对象:

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

两者都包含BusinessUnit属性,而EF似乎并不想允许这样做。当执行带有一堆包含的Linq查询时,看到我在Index()方法下面出现以下错误。

  

引入FOREIGN KEY约束   ' FK_dbo.Quotes_dbo.BusinessUnits_BusinessUnitId'桌子上   '行情'可能会导致循环或多个级联路径。指定ON DELETE   无动作或更新无动作,或修改其他外键   限制。无法创建约束。查看以前的错误。

有人可以向我解释为什么我会收到此错误以及我如何解决这个问题。感谢。

编辑:

这肯定是由于在Quote对象和Employee对象中都包含了BusinessUnit属性。我只是不明白为什么。

编辑2:

BusinessUnit类的代码:

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

3 个答案:

答案 0 :(得分:5)

现在,如果您尝试删除Employee,它将尝试删除Quote,该Quote的BusinessUnit,然后删除该BusinessUnit的Employees等。

使一些关系可选,或者关闭级联约定,如下所示:

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

答案 1 :(得分:0)

添加评论作为答案:这是BusinessUnitId属性与BusinessUnit属性之间的冲突

从Quote和Employee类中删除BusinessUnitId属性

答案 2 :(得分:0)

这个问题的核心是SQL Server拒绝允许循环引用的级联删除(正如@Oskar讨论的SO链接)。 EF正在将SQL Server的异常转发给您。它由代码优先的默认行为触发:“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.

您应该能够通过在Quote或Employee上至少使一个BusinessUnitId属性可以为空来克服这个问题。或者,您可以使用EF的流畅api来指定cascade delete规则。