我有一个问题,当我试图添加约束到我的表。我得到了错误:

在表'Employee'上引入外键约束'FK74988DB24B3C886'可能会导致循环或多个级联路径。指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他外键约束。

我的约束是在Code表和employee表之间。Code表包含Id, Name, FriendlyName, Type和Value。雇员有许多引用代码的字段,因此每种类型的代码都有一个引用。

我需要字段被设置为空,如果引用的代码被删除。

你知道我该怎么做吗?


当前回答

我用ASP解决了这个问题。NET Core 2.0和EF Core 2.0是按以下顺序执行的:

在包管理控制台(PMC)中运行update-database命令来创建数据库(这将导致“引入外键约束…”可能导致循环或多个级联路径。"错误) 在PMC中运行script-migration -Idempotent命令,创建一个可以不受现有表/约束而运行的脚本 使用结果脚本并找到ON DELETE CASCADE并替换为ON DELETE NO ACTION 对数据库执行修改后的SQL

现在,您的迁移应该是最新的,级联删除应该不会发生。

太糟糕了,我在实体框架核心2.0中找不到任何方法来做到这一点。

好运!

其他回答

听起来,你有一个OnDelete/OnUpdate动作在你现有的外键之一,这将修改你的代码表。

通过创建这个外键,你会创建一个循环问题,

例如,更新Employees,导致代码被一个On Update Action改变,导致Employees被一个On Update Action改变…等等……

如果你发布了两个表的表定义,以及你的外键/约束定义,我们应该能够告诉你问题在哪里…

SQL Server对级联路径进行简单的计数,而不是试图计算是否存在任何循环,它假设最坏的情况并拒绝创建引用操作(cascade):您可以并且应该仍然在没有引用操作的情况下创建约束。如果你不能改变你的设计(或者这样做会损害一些东西),那么你应该考虑使用触发器作为最后的手段。

FWIW求解级联路径是一个复杂的问题。其他SQL产品将简单地忽略这个问题,并允许您创建循环,在这种情况下,它将是一场比赛,看看谁将最后覆盖的值,可能是设计师的无知(例如ACE/Jet这样做)。我知道一些SQL产品将尝试解决简单的情况。事实是,SQL Server甚至没有尝试,它通过禁止多个路径来保持超级安全,至少它会告诉你。

微软自己建议使用触发器而不是FK约束。

一些数据库,尤其是SQL Server,对形成循环的级联行为有限制。 有两种方法可以处理这种情况: 1.将一个或多个关系更改为不级联删除。 2.配置数据库时不要使用一个或多个级联删除,然后确保加载所有相关实体,以便EF Core可以执行级联行为。 请参阅此连结: 数据库级联限制

这是数据库触发策略类型的错误。触发器是代码,可以向级联关系(如级联删除)添加一些智能或条件。你可能需要专门化相关的表选项,比如关闭CascadeOnDelete:

protected override void OnModelCreating( DbModelBuilder modelBuilder )
{
    modelBuilder.Entity<TableName>().HasMany(i => i.Member).WithRequired().WillCascadeOnDelete(false);
}

或者完全关闭此功能:

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

有一篇文章解释了如何使用触发器执行多个删除路径。也许这对于复杂的场景很有用。

http://www.mssqltips.com/sqlservertip/2733/solving-the-sql-server-multiple-cascade-path-issue-with-a-trigger/