2016-11-16 2 views
3

У меня есть три таблицы, которые связаны внешними ключами. Я пытаюсь вставить одну строку в таблицу вопросов и две строки в две другие таблицы. Я получаю ошибку «Вставить заявление конфликт с ограничением внешнего ключа» Спасибо заранее за помощьВставить сразу несколько связанных таблиц в Entity

public void setMultiAnswer() 
{ 
try 
{ 
    string question = "Question 1" 
    responsesList.Add("Answer1"); 
    responsesList.Add("Answer2"); 
    questionResponsesList.Add(false); 
    questionResponsesList.Add(true); 

    using (Entities testEntity = new Entities()) 
    { 
     Question questionObj = new Question(); 
     questionObj.Question1 = question; 
     questionObj.CreatedBy = "test"; 
     questionObj.CreatedDate = DateTime.Now; 

     QuestionRespons questionResponsesObj = new QuestionRespons(); 
     // fill response 
     foreach (var questionResponse in questionResponsesList) 
     { 
      questionResponsesObj.CorrectResponse = questionResponse; 
     } 

     questionObj.QuestionResponses.Add(questionResponsesObj); 

     Response responseObj = new Response(); 

     // fill response 
     foreach (var response in responsesList) 
     { 
      responseObj.Response1 = response; 
      responseObj.CreatedBy = "test"; 
      responseObj.CreatedDate = DateTime.Now; 
     } 
     questionResponsesObj.Response = responseObj; 

     testEntity.Questions.Add(questionObj); 
     testEntity.SaveChanges(); 
    } 
} 
catch (Exception ex) 
{ 
    Console.Write(ex); 
} 
+0

Вы не можете найти код модели? – Sampath

+0

Спасибо, я добавил часть модели. – user6934713

ответ

2

Похоже, ваш вопрос идентификатор генерируется автоматически. В этом случае int questionId = questionObj.QuestionID; будет работать только после вызова SaveChanges().

В общем случае, если у вас есть EntitySet с внешними ключами, проще использовать свойства навигации, а не самостоятельно создавать ссылки на идентификаторы.

Question questionObj = new Question(); 
questionObj.CreatedBy = "Test"; 
questionObj.CreatedDate = DateTime.Now; 

QuestionRespons questionResponsesObj = new QuestionRespons(); 
// fill question response here 
questionObj.QuestionResponses.Add(questionResponseObj); 

Response responseObj = new Response(); 
// fill your response here 
questionResponsesObj.Response = reponseObj; 
// if you do the above in your loop you should be fine 

testEntity.Questions.Add(questionObj); 
testEntity.SaveChanges(); 

Чтобы соответствовать вашему примеру:

public void setMultiAnswer() 
{ 
    try 
    { 
     string question = "Question 1" 
     responsesList.Add("Answer1"); 
     responsesList.Add("Answer2"); 
     questionResponsesList.Add(false); 
     questionResponsesList.Add(true); 

     using (Entities testEntity = new Entities()) 
     { 
      Question questionObj = new Question(); 
      questionObj.Question1 = question; 
      questionObj.CreatedBy = "Test"; 
      questionObj.CreatedDate = DateTime.Now; 
      testEntity.Questions.Add(questionObj); 

      for (int i = 0; i < responsesList.Count; i++) 
      { 
       // i am not sure about your relation here, but i assume you require one QuestionResponse per response 
       // which is why a moved the line of code 
       QuestionRespons questionResponsesObj = new QuestionRespons(); 
       questionObj.QuestionResponses.Add(questionResponsesObj); 

       Response responseObj = new Response(); 
       responseObj.Response1 = responsesList.ElementAt(i); 
       responseObj.CreatedBy = "Test"; 
       responseObj.CreatedDate = DateTime.Now; 

       if (!string.IsNullOrEmpty(responseObj.Response1)) 
       { 
        questionResponsesObj.Response = responseObj; 
        questionResponsesObj.CorrectResponse = questionResponsesList.ElementAt(i); 
       } 

      } 
      testEntity.SaveChanges(); 
     } 
    } 
    catch (Exception ex) 
    { 
     Console.Write(ex); 
    } 
} 
+0

Спасибо. Мне также нужно вставить в таблицу Response. И таблица questionResonses имеет внешние ключи из двух других таблиц. – user6934713

+0

Я обновил excample до Inculde Response, я не уверен в ваших отношениях между 'QuestionResponses' и' Reponse', поэтому я не включил ваш цикл for в пример , – jpk

1

изменить порядок

int questionId = questionObj.QuestionID; 
testEntity.SaveChanges(); 

в

testEntity.SaveChanges(); 
int questionId = questionObj.QuestionID; 

Вы создали новый экземпляр questionObj который должен иметь значение по умолчанию ID от 0 Только после вызова SaveChanges() идентификатору должно быть присвоено новое назначенное фактическое значение идентификатора.

Итак, что здесь происходит, это то, что вы запоминаете questionId со значением по умолчанию 0 вместо реального ID. В качестве следствия отношения между вопросами и ответами всегда будут ошибочными.

+0

Это разбивает атомный процесс на две транзакции - не очень хорошо. –

+0

@GertArnold Согласен! Я тоже не смог бы это реализовать. Я просто хотел оставить ответ коротким и без полного переписывания полного кода. –

1

Если бы я был вами, я бы удалил эту таблицу QuestionResponse, чтобы сохранить только вопрос и ответ. Используйте свойства навигации вместо прямой установки внешнего ключа.

Question questionObj = new Question 
    { 
     Text = question, 
     CreatedBy = "Test", 
     CreatedDate = DateTime.Now 
    }; 

    foreach(var response in responsesList.Where(x => !string.IsNullOrEmpty(x))) 
    { 
     Response responseObj = new Response 
     { 
      Text = response, 
      IsCorrect = true, 
      CreatedBy = "Test", 
      CreatedDate = DateTime.Now 
     } 

     questionObj.Add(responseObj); 
    } 

    testEntity.Questions.Add(questionObj); 
    testEntity.SaveChanges(); 
+0

Как включить ответ вопроса – user6934713

+0

Нет, объект 'QuestionResponse' не может быть удален из модели, но настройка свойств навигации вместо значений FK является абсолютно правильной! –

+0

Я изменил код в соответствии с вашим предложением (вы можете увидеть код выше). Но я вхожу только в один вопрос. Ответ и ответ вместо двух. – user6934713

Смежные вопросы