【问题标题】:Entity Framework Error Deleting Entity with Foreign Key Relationship实体框架错误删除具有外键关系的实体
【发布时间】:2015-08-01 19:46:34
【问题描述】:

由于外键关系,我在删除某些实体时遇到问题。我了解以下错误消息,并已尽我所能删除实体而不会出现此错误:

DELETE 语句与 REFERENCE 约束冲突 “FK_QuizUserAnswer_QuizWithQuestion”。冲突发生在 数据库“SomeDatabase”,表“dbo.QuizUserAnswer”,列 'idQuiz问题'。声明已终止。

这是两张相关表格的图片:

我正在尝试删除 QuizWithQuestion 实体。我已将 idQuizQuestion 列设为可为空。因此,外键在 QuizUserAnswer 端可以为空。 在映射文件中,我已指定关系是可选

HasMany(t => t.QuizUserAnswers)
    .WithOptional(t => t.QuizWithQuestion)
    .HasForeignKey(t => t.idQuizQuestion);

HasOptional(t => t.QuizWithQuestion)
    .WithMany(t => t.QuizUserAnswers)
    .HasForeignKey(d => d.idQuizQuestion);

我已经尝试了很多很多sn-ps的代码,所以我将代码的当前状态发布,希望我的意图是明确的:

    public void RemoveQuestionsFromQuiz(IEnumerable<int> deletedQuestions, int quizId)
    {
        var quiz = // code which retrieves quiz

        foreach (var deletedQuestion in deletedQuestions)
        {
            var quizWithQuestion = quiz.QuizWithQuestions.FirstOrDefault(q => q.Id == deletedQuestion);

            if (!ReferenceEquals(null, quizWithQuestion))
            {
                db.Entry(quizWithQuestion).State = EntityState.Deleted;                    
            }
        }
        db.SaveChanges();
    }

另一个尝试如下所示:

public void RemoveQuestionsFromQuiz(IEnumerable<int> deletedQuestions, int quizId)
{
    var quiz = // code which retrieves quiz

    foreach (var deletedQuestion in deletedQuestions)
    {
        var quizWithQuestion = quiz.QuizWithQuestions.FirstOrDefault(q => q.Id == deletedQuestion);

        if (!ReferenceEquals(null, quizWithQuestion))
        {
            foreach (var quizUserAnswer in quizWithQuestion.QuizUserAnswers)
            {
                quizUserAnswer.idQuizQuestion = null; // nullable
                quizWithQuestion.QuizUserAnswers.Remove(quizUserAnswer);
                db.Entry(quizUserAnswer).State = EntityState.Modified;
            }

            quiz.QuizWithQuestions.Remove(quizWithQuestion);

            db.Entry(quizWithQuestion).State = EntityState.Deleted;
        }
    }
    _db.SaveChanges();
}

如何删除这些该死的实体(我已经快要编写存储过程了)?

【问题讨论】:

  • 异常表示无法删除该问题,因为有引用该问题的用户答案(不是很多字)。您正在删除测验,测验中的问题,但您是否打算也删除针对这些问题的问题(这听起来很糟糕)。还是应该以非规范化的方式存储答案而没有外键?
  • 为什么要设置入口状态?实体一开始是分离的吗?如果它们已经附加,很多行似乎是多余的。
  • @Smudge202 我确实希望能够删除 QuizWithQuestion,但留下孤立的 QuizUserAnswer。通过拥有一个可为空的外键,我应该能够做到这一点。我不明白为什么它不允许我这样做。
  • @jjj 我只关心删除实体。我不介意在这个阶段是否有大量的冗余行。其中一些是冰雹玛丽的。我只想完成工作。

标签: entity-framework entity-framework-6 poco


【解决方案1】:

由于您已经有要删除的问题 ID,因此应该可以使用以下方法:

// assuming db is your DbContext
var questions = db.QuizWithQuestions
                  .Where(q => deletedQuestions.Contains(q.Id))
                  .Include(q => q.QuizUserAnswers);

// assuming this is your DbSet
db.QuizWithQuestions.RemoveRange(questions);

db.SaveChanges();

如果 QuizUserAnswer 实体被加载到上下文中(这是 include 应该做的),实体框架应该处理将外键设置为 null。

【讨论】:

  • 踢自己。我忘了提前包括。为树之林。我知道这会很简单。
猜你喜欢
  • 1970-01-01
  • 2020-03-27
  • 1970-01-01
  • 1970-01-01
  • 2017-07-20
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多