2015-05-20 4 views
1

У меня возникла проблема с удалением некоторых объектов из-за отношения внешнего ключа. Я понимаю следующее сообщение об ошибке, и делал все, что я могу думать, чтобы удалить объекты, не подвергаясь эту ошибку:Ошибка Entity Framework Удаление сущности с внешним ключом

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.

Вот изображение из двух таблиц в вопросе:

enter image description here

Я пытаюсь удалить QuizWithQuestion объектов. Я сделал столбец idQuizQuestion nullable. Таким образом, внешний ключ недействителен на стороне 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); 

Я пробовал много, много фрагментов кода, так что я буду размещать текущее состояние кода в надежде, что мое намерение ясно:

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(); 
} 

Как я могу удалить эти штопать оздействию (я настолько близок к написанию хранимой процедуры)?

+1

Исключение говорит, что вопрос не может быть удален, поскольку есть ответы пользователей, ссылающиеся на вопрос (не так много слов). Вы удаляете викторину, вопросы по викторине, но планируете ли вы также удалять вопросы по этим вопросам (это звучит плохо). Или вы должны хранить ответы денормализованным образом без внешних ключей? – Smudge202

+0

Почему вы устанавливаете состояния записи? Разве организации начинают отключать? Если они уже подключены, многие строки кажутся излишними. – jjj

+0

@ Smudge202 Я хочу, чтобы иметь возможность удалить QuizWithQuestion, но оставить осиротевший QuizUserAnswer. Имея нулевой внешний ключ, я должен это сделать. Я не понимаю, почему это не позволит мне это сделать. – onefootswill

ответ

3

Поскольку у вас уже есть вопрос идентификаторы, чтобы удалить, что-то, как это должно работать:

// 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 объектов загружается в контекст (что включает должен сделать), Entity Framework должна обрабатывать установки внешние ключи равны нулю.

+0

Удар себя. Я забыл ** включить **, что впереди. Лес для деревьев. Я знал, что это будет что-то простое. – onefootswill