我一直在冥思苦想,这一段时间,不能完全弄清楚发生了什么。我有一个包含边的卡实体(通常为2) - 和两个卡和侧面有一个舞台上。我使用的是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:
引进国外KEY约束'FK_dbo.Sides_dbo.Cards_CardId上 表'边'可能会导致循环或多重级联路径。指定ON DELETE NO行动或UPDATE没有行动,或者修改其他外国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; }
}
下面是我的侧实体:
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; }
}
和这里是我的舞台实体:
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
已被添加到卡
(如预期/需要的话),但边
没有提及舞台
(不期望)。
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; }
我身边班,我看 StageId
列添加到我的侧
表。
To my Side class, I see StageId
column added to my Side
table.
这是工作,但现在在我的应用程序,任何引用舞台
包含 SideId
,这是在某些情况下完全无关。 我想只要给我卡
和侧
实体舞台
属性基于上述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?
由于舞台
是要求的都是一个一对多的关系,其中舞台
是参与将有级联删除默认情况下启用。这意味着,如果删除舞台
实体
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
侧
删除将直接级联到卡
因为卡
和侧
已与级联所需的一个一对多的关系删除默认启用再次它将再级联从卡
到侧
the delete will cascade directly to Side
the delete will cascade directly to Card
and because Card
and Side
have a required one-to-many relationship with cascading delete enabled by default again it will then cascade from Card
to Side
所以,你有两个级联删除舞台
路径侧
- 这将导致异常。
So, you have two cascading delete paths from Stage
to Side
- which causes the exception.
您必须要么使舞台
可选的实体中的至少一个(即删除 [必需]
从舞台
属性的属性)或禁止用流利的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);