2个表,从一个表接收Id并将值添加到另一个表但具有id

时间:2018-05-08 09:23:41

标签: asp.net asp.net-mvc asp.net-core

我的网络应用是关于在线资讯池的,它有Model.QuestionModel.Answer

有问题我有IdText(问题的价值),List of AnswersStartDateEndDate以及active

在答案模型中,我有IdQuestionIdText(答案的价值)和Votes(现在不想使用它)

当我从问题(ID)中检索值时,我遇到了问题,因此Answer.QuestionId有ID。然后我需要将Model.Answer.Text添加到Question.Answer;

这是我的控制器:

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

1 个答案:

答案 0 :(得分:0)

所以,你可以改变你的代码(为了简洁而省略了控制器的其余部分),如下所示:

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

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

  • Answer上的ID是一个带有自动增量设置的int。如果是这种情况那么它将起作用。例如,如果它是Guid,那么您需要先创建Id,所以请记住这一点。
  • 你有repository,我不知道它是什么。但是,既然你正在那里使用dbContext,我没有看到它的使用,所以在我的解决方案中完全被忽略

并且......给你一些其他建议:

  • 请勿将EF实体用作控制器操作的类型。相反,创建一些ViewModels。 EF实体可能很复杂,并且大多数情况下您的客户只能处理其中的一部分。因此,使用其他类型返回/发布到您的操作被认为是一种很好的做法。 Read more here
  • 通常,您可以在控制器中注入DbContext。这样您就不必在控制器中实例化它,它的生命周期由DI系统管理(if you configure it correctly
  • 同时检查全局异常处理。网上有很多资源..但基本上你想要的是避免控制器中的try / catch重复异常处理。

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