0

我尝试插入一个列表,作为回报,它被插入到其中Answers,我的所有代码都可以正常工作,除了一个部分,它正在插入新的.QuestionsExamsAnswers

数据插入得很好,除了 Answers 的数据,其数据没有存储在数据库中,而且我尝试获取QuestionId,所以我可以用 Answer 作为外键存储它,但我也失败了。

API 控制器

        public IActionResult addExam([FromBody] Exams exam)
        {
            try
            {
                if (exam == null)
                {
                    return StatusCode(401, "data is null");
                }

                var userId = this.help.GetCurrentUser(HttpContext);


                Exams exams = new Exams
                {
                    Name = exam.Name,
                    Number = exam.Number,
                    FullMarck = exam.FullMarck,
                    CreatedBy = userId,
                    CreatedOn = DateTime.Now,
                    Status = exam.Status
                };
               db.Exams.Add(exams);

                var questionsList = new List<Questions>();

                foreach (Questions item in exam.Questions)
                {
                    var question = new Questions
                    {

                        ExamId = exam.Id,
                        Points = item.Points,
                        CreatedBy = userId,
                        CreatedOn = DateTime.Now,
                        Status = item.Status,
                    };
                    questionsList.Add(question);

                }

               exams.Questions = questionsList;
                db.SaveChanges();
                foreach (Questions item in exam.Questions)
                {

                    var answersList = new List<Answers>();
                    foreach (Answers answers in item.Answers)

                        answersList.Add(new Answers
                        {
                            QuestionId = item.Id,
                            ExamAnswers = answers.ExamAnswers,
                            CreatedBy = userId,
                            CreatedOn = DateTime.Now
                        });
                    item.Answers = answersList;

                }

                db.SaveChanges();
                return Ok("successfully created ");
            }
            catch (Exception e)
            {
                return StatusCode(500, e.InnerException.Message);
            }

        }
4

4 回答 4

1

您构建图表的方式有点不寻常。我本来希望它更像是一组嵌套循环,它采用您提供的模型并填充实体集合而无需强制 id。EF 将跟踪 ID;您无需担心它们;当您向特定 question.Answers 集合添加新的 Answer 时,您无需告诉 Answer 它的 QuestionID 是什么;EF 知道它添加到哪个问题。如果尚未设置问题的 ID,因为它是由 db 生成的并且没有发生保存,则保存问题将生成一个 ID,EF 会将更改波及问题中所有拥有的答案。答案;你不需要微观管理它

这是我期望它如何运行的伪代码:

//model is an ExamModel

Exam e = new Exam(); //exam is a db entity
e.Title = model.ExamTitle; //model is not a db entity

foreach(QuestionModel mq in model.Questions){ //enumerate all the questionmodel we got from the front end and build a db entity graph 

  Question q = new Question(); //make new db entity

  q.Subject = mq.QuestionHeader; //set entity property from model
  q.Body = mq.BodyText; //set property from model

  if(e.Questions == null) //not sure how your entities are declared, if this is already done elsewhere, remove it
    e.Questions = new List<Question>();

  e.Questions.Add(q); //add the question db entity to the exam db entity

  //notice I didn't set the question id. EF will do that- it knows what exam this question belongs to

  foreach(AnswerModel ma in mq.Answers){ //while our question db entity called q is still in scope let us add the related answers to it

    Answer a = new Answer(); //create EF entity
    a.Text = ma.AnswerText; //set db entity property from model property

    if(q.Answers == null)
      q.Answers = new List<Answer>();

    q.Answers.Add(a); //add the answer to the question db entity 
  }

}
//exam e now has a collection of questions that have each a collection of answers, save it to the db 
db.Exams.Add(e);
db.SaveChanges(); //only need one call to save changes on the whole graph

我认为您拆分操作的方式并没有创建实体的连接图和/或您强制回答问题的方式意味着 EF 在保存时没有保持最新的关系。

您还应该将到达控制器的数据对象(我称之为 ModelExam、ModelQuestion、ModelAnswer)和 EF 中的实体(我称之为考试、问题、答案——你的这些是复数)分开。这种分离是通过为前端控制器等使用与后端数据库上下文使用不同的类来实现的。起初看起来事情正在无缘无故地重复,但最终系统将变得足够复杂,以至于并非每个数据库属性都可以或应该一直暴露到前端和后端,并且前端可能需要计算或其他非基于数据库的数据。此时,您确实需要将前端数据模型与后端数据实体完全分开

于 2020-03-27T06:54:07.100 回答
0

我认为您需要在添加新考试后调用 db.SaveChanges() 。在您的情况下,考试 ID 不是自动生成的,并且始终为 0 ,因此您无法使用考试 0 保存问题;

于 2020-03-27T06:22:36.043 回答
0

item.Answers = 答案列表;是假的exam.Questions.Answers = answersList 是真的

于 2020-03-27T06:23:25.223 回答
0

删除第一个db.SaveChanges();女巫是在最后一个foreach循环之前。这将一次插入所有数据,并且应该可以完成这项工作。

于 2020-03-27T06:38:59.853 回答