我试图更改我的控制器从视图中返回的对象。当我调试并逐步执行该程序并查看job.JobTypesId和job.JobStatusID的值时,正在显示正确的值,但是在其他所有操作时都不会保存它们。我已经阅读了几篇文章,解释了框架需要知道模型已经发生变化,以及实体状态应该做什么(http://www.mattburkedev.com/saving-changes-with-entity-framework-6-in-asp-dot-net-mvc-5/)。我也试过使用UpdateModel但是这个剂量似乎也有效(http://forums.asp.net/t/1807184.aspx?MVC+4+Not+saving+data+after+edit)。我收到一条消息"类型' StaffServiceTracker.Models.Job'无法更新。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(Job job) {
var task = from t in db.JobTypes where t.JobTypeID == job.JobTypesID.JobTypeID select t;
var status = from s in db.Statuses
where s.StatusID == job.JobStatusID.StatusID
select s;
job.JobTypesID = task.FirstOrDefault();
job.JobStatusID = status.FirstOrDefault();
db.Entry(job).State = EntityState.Modified;
db.SaveChanges();
return RedirectToAction("Index");
}
任何指导都将不胜感激。
答案 0 :(得分:2)
首先,您应该使用ViewModel(在90%的情况下)而不是视图中的业务对象。这是因为您只需将必要的数据发送到客户端,您可以组合业务对象等。
其次,一旦您在控制器中收到ViewModel,您应该首先验证它(始终在客户端和服务器端验证,因为可以绕过客户端验证)。
验证完所有内容后,使用EF从数据库中获取Job对象并设置属性。调用SaveChanges,就是这样。如果将此代码从控制器移动到服务层,会更好。
还有一件事:您可以使用SQL Server Profiler确切地知道EF正在执行哪些查询。这样你就会明白发生了什么。
[HttpPost]
[ValidateAntiForgeryToken]
public ActionResult Edit(JobVM jobVM) {
// validate VM
// ...
// the following code should be in the Service Layer but I'll write it below to simplify
// get job from DB
var job = db.Jobs.SingleOrDefault(p => p.Id == jobVM.Id);
job.JobTypesID = jobVM.JobTypesID;
job.JobStatusID = jobVM.StatusId;
db.SaveChanges();
return RedirectToAction("Index");
}