【问题标题】:FK on table may cause multiple cycles or multple cascade pathsFK on table 可能会导致多个循环或多个级联路径
【发布时间】:2019-04-26 06:55:17
【问题描述】:

我正在创建一个如下所示的数据库:我有 Questions 表:

public class Question
{
    [Key]
    public int Id { get; set; }
    public List<Answer> Answers { get; set; }
    public List<SendedAnswer> SendedAnswers { get; set; }
}

有人可以向每个问题发送SendedAnswer

public class SendedAnswer
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("Question")]
    public int QuestionId{ get; set; }

    public Question Question { get; set; }

    public List<ExecutionResult> ExecutionResults { get; set; }
}

发送答案时,我的系统会检查答案是否与输出相关

ExecutionResultID 存储到SendedAnswerAnswer(我添加了AnswerId,下面显示的错误显示在update-database 的输出中,之后添加了具有此ID 的新迁移)。在我后面的代码中,我正在检查SendedAnswer 和与Question 相关的Answers(发送SendedAnswer 以解析Question)。

public class ExecutionResult
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("SendedAnswer")]
    public int SendedAnswerId { get; set; }

    public SendedAnswer SendedAnswer { get; set; }

    [ForeignKey("Answer")]
    public int AnswerId { get; set; }

    public Answer Answer { get; set; }
}

Answers 表如下所示:

public class Answer
{
    [Key]
    public int Id { get; set; }

    [ForeignKey("Question")]
    public int QuestionId{ get; set; }

    public Question Question{ get; set; }
}

ExecutionResult 类中添加用于存储AnswerId 的新列的迁移后,我收到此错误:

在表“ExecutionResults”上引入 FOREIGN KEY 约束“FK_dbo.ExecutionResults_dbo.Answers_AnswerId”可能会导致循环或多个级联路径。指定 ON DELETE NO ACTION 或 ON UPDATE NO ACTION,或修改其他 FOREIGN KEY 约束。 无法创建约束或索引。查看以前的错误。

当我将此行添加到我的 DbContext 时(在被覆盖的方法中):

modelBuilder.Conventions.Remove<OneToManyCascadeDeleteConvention>();

我收到错误,我的 IdentityUsers 缺少几个 IDs 等(我的 DbContext 继承自 IdentityDbContext&lt;User&gt;)。

我的问题是,如何处理这个错误?当我在删除路径上获得多个级联时?对我来说它看起来不错,因为在删除 Answer 之后我想删除 ExecutionResult 并且看起来很明显我需要在 ExecutionResultAnswerSendedAnswer 中的 FK。

如何将Answers 表与ExecutionResult 表匹配而不会出现该错误?我在这里做错了什么?

【问题讨论】:

  • 其实你不需要excutionResult表,把用户回答放到SendAnswer表中,或者如果你想把更多详细信息放到ExecutionResult表中,那么你应该从ExecutionResult表中删除AnswerID,根据SendAnswerId你可以得到AnswerID .
  • 我需要执行表。 SendedAnswer store Code, ExecutionResult store Output 来自此代码。我需要另一个表来存储该输出并检查相关问题的答案
  • 如果我们在Question 中有 4 个答案,我需要 4 个 ExecutionResult,因为每个答案都会触发 ExecutionResult(4 个答案,4 个结果)
  • 当你发送一个答案,那么它是发送(不是“发送”)......
  • @michasaucer 检查我的答案!它会解决你的问题!

标签: c# entity-framework


【解决方案1】:

在外键约束上添加[Required] 属性以强制级联删除。 或者,根据您的需要,使用实体框架 fluent api 来定义其他一些 OnDelete 行为。 (https://www.learnentityframeworkcore.com/configuration/fluent-api/ondelete-method)

【讨论】:

    【解决方案2】:

    OnModelCreating(DbModelBuilder modelBuilder)中删除modelBuilder.Conventions.Remove&lt;OneToManyCascadeDeleteConvention&gt;();并添加如下Fluent API配置如下:

    protected override void OnModelCreating(DbModelBuilder modelBuilder)
    {
          base.OnModelCreating(modelBuilder);
    
          modelBuilder.Entity<ExecutionResult>().HasRequired(er => er.SendedAnswer)
                .WithMany(sa => sa.ExecutionResults).HasForeignKey(er => er.SendedAnswerId)
                .WillCascadeOnDelete(false);
    
          modelBuilder.Entity<ExecutionResult>().HasRequired(er => er.Answer)
                .WithMany().HasForeignKey(er => er.AnswerId).WillCascadeOnDelete(false);
    }
    

    现在再次生成迁移并更新数据库。

    【讨论】:

      猜你喜欢
      • 2018-12-19
      • 2022-01-05
      • 2020-02-04
      • 2016-03-26
      • 2019-09-22
      • 1970-01-01
      • 2021-08-12
      • 2016-07-22
      • 2020-06-14
      相关资源
      最近更新 更多