.net - 引入 FOREIGN KEY 约束可能会导致循环或多个级联路径 - 为什么?

标签 .net entity-framework foreign-keys ef-code-first entity-framework-4

我已经为此苦苦挣扎了一段时间,但不太明白发生了什么。我有一个包含 Sides(通常是 2 个)的 Card 实体 - 并且 Cards 和 Sides 都有一个 Stage。我正在使用 EF Codefirst 迁移,但迁移失败并出现以下错误:

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; }

}

这是我的舞台实体:

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,这在某些情况下完全不相关。 我只想为我的 CardSide 实体提供基于上述 Stage 类的 Stage 属性,而不会污染 stage 类如果可能的话,使用引用属性...我做错了什么?

最佳答案

由于 Stage必需,因此涉及 Stage 的所有一对多关系都将默认启用级联删除。这意味着,如果您删除 Stage 实体

  • 删除将直接级联到Side
  • 删除将直接级联到 Card,并且因为 CardSide 具有所需的一对多关系,并且通过以下方式启用级联删除:再次默认,它将从 Card 级联到 Side

因此,您有两个从 StageSide 的级联删除路径 - 这会导致异常。

您必须在至少一个实体中将 Stage 设置为可选(即从 Stage 属性中删除 [Required] 属性)或使用 Fluent API 禁用级联删除(无法使用数据注释):

modelBuilder.Entity<Card>()
    .HasRequired(c => c.Stage)
    .WithMany()
    .WillCascadeOnDelete(false);

modelBuilder.Entity<Side>()
    .HasRequired(s => s.Stage)
    .WithMany()
    .WillCascadeOnDelete(false);

关于.net - 引入 FOREIGN KEY 约束可能会导致循环或多个级联路径 - 为什么?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17127351/

相关文章:

c# - 在 NHibernate 中管理 session 的最佳方式?

c# - 我应该在 DropCreateDatabaseIfModelChanges 中还是在 DbMigrationsConfiguration 中播种数据库?

MySql/Cloudbees VARCHAR 作为外键

Symfony2,DoctrineFixturesBundle,由于外键约束无法加载夹具

c# - 将卢比符号添加到我的 gridview 列

.net - .NET Reflector 指令的命名空间

.net - 获取自定义用户控件中声明的事件的所有事件处理程序

.net - 如何在不打数据库的情况下获取独立关联的外键值?

c# - Entity Framework 不支持 protected 导航属性吗?

mysql - 从数据库中删除可能有子项的记录