【发布时间】:2017-07-31 18:32:26
【问题描述】:
我有一个“创建”ActionResult,它正在从视图传回数据,但数据没有保存到数据库中。我知道数据正在正确地传递给控制器,因为我已经使用调试器完成了整个过程,但是当 POST 操作完成时,数据没有保存。 “项目”已创建,但未保存用户(公共虚拟,因此它实际上存储在名为 ApplicationUserProjects 的表中)字段。该字段是在代码运行时填充的,但是一旦操作完成,数据就不会添加到该表中,据我所知,它已经完全消失了。这是来自控制器的代码:
[HttpPost]
[ValidateAntiForgeryToken]
[Authorize(Roles = "Administrator, Project Manager, SuperUser")]
public ActionResult Create([Bind(Include = "Id,Name")] Project project, List<string> Developers, List<string> ProjectManagers)
{
if (ModelState.IsValid)
{
db.Projects.Add(project);
db.SaveChanges();
var projectsHelper = new ProjectsHelper();
foreach (var user in Developers)
{
projectsHelper.AssignUserToProject(user, project);
//project.Users.Add(db.Users.FirstOrDefault(u => u.Id == user));
//db.SaveChanges();
}
foreach (var user in ProjectManagers)
{
projectsHelper.AssignUserToProject(user, project);
//project.Users.Add(db.Users.FirstOrDefault(u => u.Id == user));
//db.SaveChanges();
}
return RedirectToAction("Index");
}
return View(project);
}
foreach 循环中被注释掉的代码代表我为解决这个问题所做的不同努力,但没有成功。
这是控制器使用的辅助方法:
public bool AssignUserToProject(string userId, Project project)
{
if (!IsUserAssignedToProject(userId, project))
{
project.Users.Add(db.Users.FirstOrDefault(u => u.Id == userId));
//project.Users.Add(user);
}
if (IsUserAssignedToProject(userId, project))
{
db.SaveChanges();
return true;
}
else
{
return false;
}
}
我不知道这是否重要,但这里是处理这些输入字段的视图部分:
<div class="form-horizontal">
<h4>Project</h4>
<hr />
@Html.ValidationSummary(true, "", new { @class = "text-danger" })
<div class="form-group">
@Html.LabelFor(model => model.Name, htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.EditorFor(model => model.Name, new { htmlAttributes = new { @class = "form-control", style = "max-width:300px;" } })
@Html.ValidationMessageFor(model => model.Name, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@*@Html.LabelFor(model => model.Users, htmlAttributes: new { @class = "control-label col-md-2" })*@
@Html.Label("Developers", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.ListBox("Developers", null, htmlAttributes: new { @class = "form-control", style = "max-width:300px;" })
@Html.ValidationMessageFor(model => model.Users, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
@*@Html.LabelFor(model => model.Users, htmlAttributes: new { @class = "control-label col-md-2" })*@
@Html.Label("Project Managers", htmlAttributes: new { @class = "control-label col-md-2" })
<div class="col-md-10">
@Html.ListBox("ProjectManagers", null, htmlAttributes: new { @class = "form-control", style = "max-width:300px;" })
@Html.ValidationMessageFor(model => model.Users, "", new { @class = "text-danger" })
</div>
</div>
<div class="form-group">
<div class="col-md-offset-2 col-md-10">
<input type="submit" value="Create" class="btn btn-default" />
</div>
</div>
</div>
提前谢谢你!
编辑: 如果我移动 db.SaveChanges();在 foreach 块下方的任何位置行,当到达该行时,我收到此错误:“EntityFramework.dll 中发生'System.InvalidOperationException'类型的异常,但未在用户代码中处理{“两个对象之间的关系不能定义是因为它们附加到不同的 ObjectContext 对象。"}"
【问题讨论】:
-
执行所有操作,最后添加
db.SaveChanges(),重定向可以解决您的问题。从所有其他地方删除db.SaveChanges()。 -
您不需要多次调用 SaveChanges()。如图here 所示,编写您的对象图并一次性保存。对于现有的孩子,您可能需要设置他们的entity state,或者您可以通过外键而不是导航属性进行更新。
标签: c# asp.net-mvc entity-framework