从控制器编辑操作更新实体的正确方法?

时间:2012-03-19 18:09:30

标签: c# asp.net-mvc entity-framework ef-code-first

控制器

首先我尝试了这个:

[HttpPost]
public ActionResult Edit(JournalEntry journalentry)
{
    if (ModelState.IsValid)
    {
        db.Entry(journalentry).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index", new { id = journalentry.Journal.JournalId });
    }
    return View(journalentry);
}

SaveChanges()

引发了错误
  

错误消息:“存储更新,插入或删除语句受影响   意外的行数(0)。实体可能已被修改或   自实体加载后删除。刷新ObjectStateManager   条目“。

我查看了journalentry实体,注意到它的JournalEntryId为0,但所有其他属性都设置正确。因此,我改为:

[HttpPost]
public ActionResult Edit(int id, JournalEntry journalentry)
{
    if (ModelState.IsValid)
    {
        journalentry.JournalEntryId = id;
        db.Entry(journalentry).State = EntityState.Modified;
        db.SaveChanges();
        return RedirectToAction("Index", new { id = journalentry.Journal.JournalId });
    }
    return View(journalentry);
}

一切看起来都能正确保存,但这是保存实体的正确方法吗?

1 个答案:

答案 0 :(得分:2)

实际上,您可以将JournalEntryId视图模型中的JournalEntry属性重命名为Id,然后默认的模型活页夹会自动为您填充它,这样您就不必编写以下一行:

journalentry.JournalEntryId = id;

并且您的第一个代码段将起作用,因为Id属性将使用路由中的值填充。

或者,如果由于某种原因你无法重命名你的视图模型上的属性(实际上我知道原因=>你根本没有使用任何视图模型,但是你将你的域实体直接传递给视图,这是不好的但是根据另一个问题),您可以在表单中使用隐藏字段:

@Html.HiddenFor(model => model.JournalEntryId)

或修改您的Html.BeginForm声明以将参数包含在查询字符串参数中:

@Html.BeginForm("Edit", "SomeController", new { JournalEntryId = Model.JournalEntryId }, FormMethod.Post)
{
    ...        
}