【发布时间】: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