4

我仍然在使用 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() 方法上收到以下错误。

在表 'Quotes' 上引入 FOREIGN KEY 约束 'FK_dbo.Quotes_dbo.BusinessUnits_BusinessUnitId' 可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。无法创建约束。请参阅以前的错误。

有人可以向我解释为什么我会收到此错误以及如何修复它。谢谢。

编辑:

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

编辑2:

BusinessUnit 类的代码:

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

3 回答 3

5

现在,如果您尝试删除一个员工,它将尝试删除报价单、该报价单的业务单元,然后是该业务单元的员工,等等。

要么使某些关系可选,要么关闭级联约定,如下所示:

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);
}
于 2013-05-23T14:23:16.793 回答
0

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

从 Quote 和 Employee 类中删除 BusinessUnitId 属性

于 2013-05-23T14:15:11.337 回答
0

这个问题的核心是 SQL Server 拒绝允许循环引用级联删除(正如@Oskar 的 SO 链接所讨论的那样)。EF 正在将异常从 SQL Server 转发给您。它是由代码优先的默认行为触发的:“如果依赖实体上的外键不可为空,则代码优先在关系上设置级联删除。如果依赖实体上的外键可以为空,则代码优先不会设置级联删除关系,当主体被删除时,外键将设置为空。 "

您应该能够通过在 Quote 或 Employee 上将至少一个 BusinessUnitId 属性设为空来解决此问题。或者,您可以使用 EF 的 fluent api 来指定级联删除规则。

于 2013-05-23T14:40:06.390 回答