我已经和它搏斗了一段时间,并且无法弄清楚发生了什么 . 我有一个卡片实体,其中包含Sides(通常为2个) - 卡片和侧面都有一个舞台 . 我正在使用EF Codefirst迁移,并且迁移失败并出现此错误:
在表'Sides'上引入FOREIGN KEY约束'FK_dbo.Sides_dbo.Cards_CardId'可能会导致循环或多个级联路径 . 指定ON DELETE NO ACTION或ON UPDATE NO ACTION,或修改其他FOREIGN KEY约束 .
这是我的 Card 实体:
public class Card
{
public Card()
{
Sides = new Collection<Side>();
Stage = Stage.ONE;
}
[Key]
[Required]
public virtual int CardId { get; set; }
[Required]
public virtual Stage Stage { get; set; }
[Required]
[ForeignKey("CardId")]
public virtual ICollection<Side> Sides { get; set; }
}
这是我的 Side 实体:
public class Side
{
public Side()
{
Stage = Stage.ONE;
}
[Key]
[Required]
public virtual int SideId { get; set; }
[Required]
public virtual Stage Stage { get; set; }
[Required]
public int CardId { get; set; }
[ForeignKey("CardId")]
public virtual Card Card { get; set; }
}
这是我的 Stage 实体:
public class Stage
{
// Zero
public static readonly Stage ONE = new Stage(new TimeSpan(0, 0, 0), "ONE");
// Ten seconds
public static readonly Stage TWO = new Stage(new TimeSpan(0, 0, 10), "TWO");
public static IEnumerable<Stage> Values
{
get
{
yield return ONE;
yield return TWO;
}
}
public int StageId { get; set; }
private readonly TimeSpan span;
public string Title { get; set; }
Stage(TimeSpan span, string title)
{
this.span = span;
this.Title = title;
}
public TimeSpan Span { get { return span; } }
}
奇怪的是,如果我将以下内容添加到Stage类中:
public int? SideId { get; set; }
[ForeignKey("SideId")]
public virtual Side Side { get; set; }
迁移成功运行 . 如果我打开SSMS并查看表格,我可以看到 Stage_StageId
已添加到 Cards
(如预期/所需),但是 Sides
不包含对 Stage
的引用(不是预期的) .
如果我再添加
[Required]
[ForeignKey("StageId")]
public virtual Stage Stage { get; set; }
public int StageId { get; set; }
在我的Side类中,我看到 StageId
列已添加到我的 Side
表中 .
这是有效的,但现在在我的应用程序中,对 Stage
的任何引用都包含 SideId
,在某些情况下完全无关紧要 . I'd like to just give my Card and Side entities a Stage property based on the above Stage class without polluting the stage class with reference properties if possible ......我做错了什么?
13 回答
当我从EF7模型迁移到EF6版本时,我收到了很多实体的错误 . 我不想一次一个地浏览每个实体,所以我使用了:
出于文档目的,对于未来的人来说,这件事可以像这样简单解决,并且使用这种方法,你可以做一个禁用一次的方法,你可以正常访问你的方法
将此方法添加到上下文数据库类:
由于
Stage
是必需的,因此涉及Stage
的所有一对多关系将默认启用级联删除 . 这意味着,如果删除Stage
实体删除将直接级联到
Side
删除将直接级联到
Card
,因为Card
和Side
具有所需的一对多关系,默认情况下启用了级联删除,然后它将从Card
级联到Side
因此,您有两个从
Stage
到Side
的级联删除路径 - 这会导致异常 .您必须在至少一个实体中使
Stage
可选(即从Stage
属性中删除[Required]
属性)或禁用使用Fluent API的级联删除(不能使用数据注释):现有的答案很棒我只是想补充一点,因为不同的原因我遇到了这个错误 . 我想在现有数据库上创建初始EF迁移,但我没有使用 -IgnoreChanges 标志并在空数据库上应用Update-Database命令(也在现有的失败上) .
相反,当当前的db结构是当前的db结构时,我必须运行此命令:
数据库结构中可能存在一个真正的问题,但一次只能拯救世界......
在.NET Core中,我将onDelete选项更改为ReferencialAction.NoAction
您可以将cascadeDelete设置为false或true(在迁移Up()方法中) . 取决于您的要求 .
这听起来很奇怪,我不知道为什么,但在我的情况下,这是因为我的ConnectionString使用“ . ” . 在“数据源”属性中 . 一旦我将其改为“localhost”,它就像一个魅力 . 无需其他任何改变 .
上述解决方案都不适合我 . 我必须做的是对不需要的外键(或非空列键)使用可空的int(int?),然后删除我的一些迁移 .
首先删除迁移,然后尝试nullable int .
问题既是修改又是模型设计 . 无需更改代码 .
我也有这个问题,我立即用this answer from a similar thread解决了
在我的情况下,我不想删除密钥删除的依赖记录 . 如果在您的情况下就是这种情况,只需将迁移中的布尔值更改为false:
如果你正在创建抛出这个编译器错误但是想要保持级联删除的关系,那么很有可能;你的人际关系有问题 .
在.NET Core中,我玩了所有上层答案 - 但没有任何成功 . 我在数据库结构中做了很多更改,并且每次都添加了尝试
update-database
的新迁移,但收到了同样的错误 .然后我一个接一个地开始
remove-migration
,直到Package Manager Console引发异常:之后,我添加了新的迁移(
add-migration
)和update-database
successfully所以我的建议是:清除所有临时迁移,直到你当前的数据库状态 .
我修好了 . 添加迁移时,在Up()方法中会有像这样的一条线:
如果你只是从最后删除cascadeDelete它将工作 .
有人想知道如何在EF核心中做到这一点:
我有一张与其他人有圆形关系的 table ,我得到了同样的错误 . 原来它是关于不可空的外键 . 如果key不可为空,则必须删除相关对象,并且循环关系不允许这样做 . 所以使用可以为空的外键 .