引入 FOREIGN KEY 约束可能会导致循环或多个级联路径 - 为什么? [英] Introducing FOREIGN KEY constraint may cause cycles or multiple cascade paths - why?
问题描述
我已经为此纠结了一段时间,但无法弄清楚发生了什么.我有一个包含 Sides(通常为 2)的 Card 实体 - Cards 和 Sides 都有一个 Stage.我正在使用 EF Codefirst 迁移,迁移失败并出现此错误:
I've been wrestling with this for a while and can't quite figure out what's happening. I have a Card entity which contains Sides (usually 2) - and both Cards and Sides have a Stage. I'm using EF Codefirst migrations and the migrations are failing with this error:
引入 FOREIGN KEY 约束 'FK_dbo.Sides_dbo.Cards_CardId' on表边"可能会导致循环或多个级联路径.指定开启DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY约束.
Introducing FOREIGN KEY constraint 'FK_dbo.Sides_dbo.Cards_CardId' on table 'Sides' may cause cycles or multiple cascade paths. Specify ON DELETE NO ACTION or ON UPDATE NO ACTION, or modify other FOREIGN KEY constraints.
这是我的卡片实体:
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 类中:
What's odd is that if I add the following to my Stage class:
public int? SideId { get; set; }
[ForeignKey("SideId")]
public virtual Side Side { get; set; }
迁移运行成功.如果我打开 SSMS 并查看表格,我可以看到 Stage_StageId
已添加到 Cards
(如预期/所需),但是 Sides
> 不包含对 Stage
的引用(不是预期的).
The migration runs successfully. If I open up SSMS and look at the tables, I can see that Stage_StageId
has been added to Cards
(as expected/desired), however Sides
contains no reference to Stage
(not expected).
如果我再添加
[Required]
[ForeignKey("StageId")]
public virtual Stage Stage { get; set; }
public int StageId { get; set; }
对于我的 Side 类,我看到 StageId
列添加到我的 Side
表中.
To my Side class, I see StageId
column added to my Side
table.
这是有效的,但现在在我的整个应用程序中,对 Stage
的任何引用都包含一个 SideId
,这在某些情况下是完全不相关的.我只想给我的 Card
和 Side
实体一个基于上述 Stage 类的 Stage
属性而不污染舞台类如果可能,使用参考属性...我做错了什么?
This is working, but now throughout my application, any reference to Stage
contains a SideId
, which is in some cases totally irrelevant. 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... what am I doing wrong?
推荐答案
因为Stage
是必需的,Stage的所有一对多关系代码> 将默认启用级联删除.这意味着,如果你删除一个
Stage
实体
Because Stage
is required, all one-to-many relationships where Stage
is involved will have cascading delete enabled by default. It means, if you delete a Stage
entity
- 删除将直接级联到
Side
- 删除将直接级联到
Card
并且因为Card
和Side
具有必需的一对多关系,通过以下方式启用级联删除再次默认它然后将从Card
级联到Side
- the delete will cascade directly to
Side
- the delete will cascade directly to
Card
and becauseCard
andSide
have a required one-to-many relationship with cascading delete enabled by default again it will then cascade fromCard
toSide
因此,您有两个从 Stage
到 Side
的级联删除路径 - 这会导致异常.
So, you have two cascading delete paths from Stage
to Side
- which causes the exception.
您必须在至少一个实体中将 Stage
设为可选(即从 Stage
属性中删除 [Required]
属性) 或使用 Fluent API 禁用级联删除(无法使用数据注释):
You must either make the Stage
optional in at least one of the entities (i.e. remove the [Required]
attribute from the Stage
properties) or disable cascading delete with Fluent API (not possible with data annotations):
modelBuilder.Entity<Card>()
.HasRequired(c => c.Stage)
.WithMany()
.WillCascadeOnDelete(false);
modelBuilder.Entity<Side>()
.HasRequired(s => s.Stage)
.WithMany()
.WillCascadeOnDelete(false);
这篇关于引入 FOREIGN KEY 约束可能会导致循环或多个级联路径 - 为什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!