首页 > 解决方案 > 2 tables, receive Id from one table and add value to another table but with id

问题描述

My web app is about an online pool, it has Model.Question and Model.Answer.

In question I have Id, Text (Value of the question), List of Answers, StartDate, EndDate and if it's active.

In the Answer model I have Id, QuestionId, Text(Value of the Answer), and Votes (don't want to use it right now)

I'm having issues when I retrieve value from Question (Id) so the Answer.QuestionId has it Id. Then I need to add my Model.Answer.Text to Question.Answer;

Here is my controller:

public ActionResult AddAnswer(int id)
{
        //return View();
        using (var poolDbContext = new PoolContext())
        {
            Answer answer = poolDbContext.Answers.Find(id);
            return View(answer);
        }
}

[HttpPost, ActionName("AddAnswer")]
[ValidateAntiForgeryToken]
public ActionResult AddAnswerPost([Bind("Id, Answers")] Question question, Answer answer)
{
        try
        {
            if (ModelState.IsValid)
            {
                using (var poolDbContext = new PoolContext())
                {
                    answer.QuestionId = question.Id;
                    poolDbContext.Answers.Add(answer);
                    question.Answers.Add(answer);
                    repository.Add(question);
                    repository.SaveChanges();
                    return RedirectToAction("Index");
                }
            }
        }
        catch (DbUpdateException /* ex */)
        {
            //Log the error (uncomment ex variable name and write a log.
            ModelState.AddModelError("", "Unable to save changes. " +
                "Try again, and if the problem persists " +
                "see your system administrator.");
        }

        return View(answer);
}

标签: asp.netasp.net-mvcasp.net-core

解决方案


因此,您可以将代码(为简洁起见省略控制器的其余部分)更改为如下所示:

using (var poolDbContext = new PoolContext())
{
    // get the question from db, also including the answers
    var questionFromDb = poolDbContext.Questions
    .Include(q => q.Answers)
    .Single(q => q.Id == question.Id);

    // good idea to validate if the question exists..
    if (questionFromDb == null)
        throw new ArgumentException("Question not found.");

    // if answer is a new answer and not an update, 
    // then just add it to the current answers.
    answer.QuestionId = questionFromDb.Id;
    questionFromDb.Answers.Add(answer);

    // dbContext is tracking changes, so you don't need to add to the dbSet.
    repository.SaveChanges();

    return RedirectToAction("Index");
}

但是..这假设了一些事情:

  • Id onAnswer是具有自动增量设置的 int。如果是这种情况,那么它将起作用。如果是Guid例如,那么您需要先创建 Id,因此请记住这一点。
  • 你有一个repository我不知道它是什么的。但是,由于您在那里使用 dbContext,我看不到它的用途,因此在我的解决方案中完全忽略了

还有..给你的一些其他建议:

  • 不要将 EF 实体用作控制器操作的类型。相反,创建一些 ViewModel。EF 实体可能很复杂,而且大多数情况下您的客户只使用其中的一部分。因此,使用另一种类型来返回/发布您的操作被认为是一种好习惯。在这里阅读更多
  • 通常,您可以在控制器中注入DbContext。这样您就不必在控制器中实例化它,它的生命周期由 DI 系统管理(如果配置正确
  • 还要检查全局异常处理。网上有很多资源..但基本上你想要的是避免在你的控制器中使用重复的异常处理来尝试/捕获。

希望它有助于澄清一些事情。


推荐阅读