Entity Framework 删除具有外键关系的实体时出错
Entity Framework Error Deleting Entity with Foreign Key Relationship
由于外键关系,我在删除某些实体时遇到问题。我了解以下错误消息,并已尽我所能删除实体而不会引发此错误:
The DELETE statement conflicted with the REFERENCE constraint
"FK_QuizUserAnswer_QuizWithQuestion". The conflict occurred in
database "SomeDatabase", table "dbo.QuizUserAnswer", column
'idQuizQuestion'. The statement has been terminated.
这是有问题的两个表的图片:
我正在尝试删除 QuizWithQuestion 个实体。我已将 idQuizQuestion 列设置为 nullable。因此,外键在 QuizUserAnswer 端可以为空。
在映射文件中,我指定关系是 optional:
HasMany(t => t.QuizUserAnswers)
.WithOptional(t => t.QuizWithQuestion)
.HasForeignKey(t => t.idQuizQuestion);
HasOptional(t => t.QuizWithQuestion)
.WithMany(t => t.QuizUserAnswers)
.HasForeignKey(d => d.idQuizQuestion);
我已经尝试了很多很多代码片段,所以我将 post 代码的当前状态,希望我的意图是明确的:
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();
}
我怎样才能删除这些该死的实体(我快要写一个存储过程了)?
由于您已经有了要删除的问题 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 应该做的),Entity Framework 应该处理将外键设置为 null。
由于外键关系,我在删除某些实体时遇到问题。我了解以下错误消息,并已尽我所能删除实体而不会引发此错误:
The DELETE statement conflicted with the REFERENCE constraint "FK_QuizUserAnswer_QuizWithQuestion". The conflict occurred in database "SomeDatabase", table "dbo.QuizUserAnswer", column 'idQuizQuestion'. The statement has been terminated.
这是有问题的两个表的图片:
我正在尝试删除 QuizWithQuestion 个实体。我已将 idQuizQuestion 列设置为 nullable。因此,外键在 QuizUserAnswer 端可以为空。 在映射文件中,我指定关系是 optional:
HasMany(t => t.QuizUserAnswers)
.WithOptional(t => t.QuizWithQuestion)
.HasForeignKey(t => t.idQuizQuestion);
HasOptional(t => t.QuizWithQuestion)
.WithMany(t => t.QuizUserAnswers)
.HasForeignKey(d => d.idQuizQuestion);
我已经尝试了很多很多代码片段,所以我将 post 代码的当前状态,希望我的意图是明确的:
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();
}
我怎样才能删除这些该死的实体(我快要写一个存储过程了)?
由于您已经有了要删除的问题 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 应该做的),Entity Framework 应该处理将外键设置为 null。