这件事我已经纠结了一段时间了,我不太明白发生了什么事.我有一个卡片实体,它包含两个侧面(通常是2个)-而且卡片和侧面都有一个stage.我正在使用EF CodeFirst迁移,迁移失败,错误如下:

引入外键约束‘fk_dbo.Sides_dbo.Cards_CardId’on 表‘侧’可能导致循环或多个级联路径.指定启用 DELETE NOT ACTION或ON UPDATE NO ACTION,或修改其它外键 约束.

以下是我的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; }

迁移成功运行.如果我打开SSM并查看表格,我可以看到Stage_StageId已添加到Cards(如预期/所需),但是Sides未包含对Stage(非预期)的引用.

如果我随后添加

    [Required]
    [ForeignKey("StageId")]
    public virtual Stage Stage { get; set; }
    public int StageId { get; set; }

在我的副课上,我看到Side表中增加了StageId列.

这是可行的,但在我的整个应用程序中,对Stage的任何引用都包含SideId,在某些情况下,这是完全无关的.I'd like to just give my 102 and 103 entities a 100 property based on the above Stage class without polluting the stage class with reference properties if possible... 我做错了什么?

推荐答案

因为Stagerequired,所以涉及Stage的所有一对多关系在默认情况下都将启用级联删除.这意味着,如果你删除了Stage个实体

  • 删除将直接级联到Side
  • 删除将直接级联到Card,因为CardSide与默认情况下再次启用的级联删除具有必需的一对多关系,所以它将从Card级联到Side

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

必须在至少一个实体中 Select 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相关问答推荐

Long.MaxValue从Single到Long的转换导致溢出异常

PowerShell 5.1和7在使用证书时的区别

Azure管道-使用.NET 8 RC2 SDK生成C#项目失败

EFCore.DbSet.Update 方法添加新行而不是更新它

为什么我在环境变量中有不同的值?

如何在选项卡中 Select Winforms NumericUpDown 中的所有文本?

是否可以模拟 .NET HttpWebResponse?

为什么我得到 411 Length required 错误?

来自奥尔森时区的 .NET TimeZoneInfo

如何防止和/或处理 StackOverflowException?

控制台应用程序的退出时

C# 中基于接口编程的运算符重载

Microsoft.Practices.ServiceLocation 来自哪里?

在 C# 中将字符串转换为十六进制字符串

MemoryStream.Close() 或 MemoryStream.Dispose()

将 StreamReader 返回到开头

哪个密码字符在 winforms 文本框中显示黑点 (•)?

在 C#/.NET 中组合路径和文件名的最佳方法是什么?

实体框架中的 POCO 是什么?

为什么 Roslyn 中有异步状态机类(而不是 struct )?