这件事我已经纠结了一段时间了,我不太明白发生了什么事.我有一个卡片实体,它包含两个侧面(通常是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相关问答推荐

从没有流的EventStore中读取流不存在异常

Ubuntu 22.04 + JetBrains Rider 不能做脚手架 dbContext

如何在 C# 中将 HTTP 发布请求发送到另一个 API?

C# 中的批量更新

您如何确定两个 HashSet 是否相等(按值,而不是按引用)?

maxRequestLength 的最大值?

通用枚举到int的C#非装箱转换?

如何在 C# 中创建 Word 文档?

如何通过 LINQ 比较没有时间的 DateTime?

Int 到字节数组

为什么 System.Timers.Timer 能在 GC 中存活,而 System.Threading.Timer 不能?

VB.NET 与 C# 整数除法

互锁且易变

为什么有些对象属性是 UnaryExpression 而有些是 MemberExpression?

立即检测客户端与服务器套接字的断开连接

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

了解 C# 中的协变和逆变接口

WebClient.DownloadString 由于编码问题导致字符损坏,但浏览器正常

使用 DateTime.ToString() 时获取日期后缀

忽略 LINQ to XML 中的命名空间