2011-12-05 56 views
7

更新对象与MVC3MVC3与EF 4.1和EntityState.Modified

我有,我可以修改模型,请参阅下面的示例:

[HttpPost] 
public ActionResult Edit(Company c) 
{ 
     if (ModelState.IsValid) 
     { 
      db.Entry(c).State = EntityState.Modified; 
      db.SaveChanges(); 
      return RedirectToAction("Index"); 
     } 
     return View(c); 
} 

该模型具有其他字段不属于在视图中显示并且不能由用户修改,但是当我单击提交按钮时,视图中未显示的字段被设置为空。

我能以某种方式让EF知道不要修改某些字段吗?谢谢。

回答

12

通常最好不要直接绑定到实体对象,而是创建一个编辑模型并绑定到该模型。

毕竟..什么阻止别人发回值,你不想改变这种方法?

这里的主要问题是,MVC模式的结合改变的情况下在模型的属性及其之前因此,主体框架不知道改了哪些值(并因此应更新)

您用db.Entry(c).State = EntityState.Modified;略微减轻了这一点,但是它告诉实体框架整个记录已更新。

我通常会做到以下几点:

  1. 绑定到一个模型专门为这个控制器首先
  2. 创建要更新的实体类的一个实例,设置相应的ID,并将其连接到上下文
  3. 更新关于实体的属性是相同的,你绑定到(物体附着,因此实体框架是跟踪哪些列现在正在改变)
  4. 的SaveChanges
  5. 模型

第三步是有点乏味,因此可以考虑使用一个工具,如automapper,使事情变得更容易

编辑:

[HttpPost] 
    public ActionResult Edit(Company c) 
    { 
     if (ModelState.IsValid) 
     { 
      Company dbCompayObjct = new Company { companyId = c.companyId }; 
      db.Company.Attach(dbCompayObjct); 

      dbCompanyObjct.CompanyName = c.CompanyName; 
      dbCompanyObjct.City = c.City; 

      db.SaveChanges(); 

      return RedirectToAction("Index"); 
     } 
     return View(c); 
    } 
+0

您好Martin,感谢您的回复,我修改了下面的代码中的编辑动作,可否请让我知道这是否是您的意思。 srry刚开始学习EF和MVC [HttpPost] 公共的ActionResult编辑(C公司){ 如果(ModelState.IsValid) { 公司dbCompanyObjct = db.Company.Find(c.companyID); dbCompanyObjct.CompanyName = c.CompanyName; dbCompanyObjct.City = c.City; db.SaveChanges(); return RedirectToAction(“Index”); } return View(c); } 另外,你能解释我什么是automapper?我如何使用它?谢谢 – Ben

+0

我很抱歉代码不对齐,难以阅读,不知道为什么它不对齐...如果代码正确,请提供建议。 – Ben

+0

这将工作,我会发布一个快速更新,虽然表明你不需要第一个例如查找 –

3

您显然会用不完整的记录覆盖您现有的记录。当你使用上面的方法时,它将完全取代现有的方法。

您可能需要填写所有不想用现有值替换的字段,或者需要获取现有记录并修改要修改的字段,然后将其保存。

+0

有没有办法以某种方式在模型类中指定例如字段“applicationDate”以不允许修改该值,类似我们如何不能修改主键模型实体? – Ben

+2

@ user1042528 - 你不理解。您正在替换整个记录,而不是更新单个字段。如果你可以防止字段被写入,那并不重要,因为你实际上并没有对它们进行写作。你正在替换整个记录。这就像是将六瓶装一瓶啤酒替换成六瓶装的不同六瓶装的区别。你没有替换其他5,你将取代整个记录。 –

+0

Thx为您解释,这是您如何更新个别字段?如果(ModelState.IsValid){ 公司dbCompanyObjct = db.Company.Find(c.companyID); dbCompanyObjct.CompanyName = c.CompanyName; dbCompanyObjct.City = c.City; db.SaveChanges(); return RedirectToAction(“Index”); } return View(c); } – Ben

0

反思并不总是坏事,有时这是你的朋友:

public ActionResult Edit(Company c) 
{ 
    if (ModelState.IsValid) 
    { 
     Company UpdateC = db.Company.find(c.CompanyID);   
     foreach (var property in typeof(Company).GetProperties()) 
     { 
      var propval = property.GetValue(c); 
      if (propval != null) 
      { 
       property.SetValue(UpdateC, propval); 
      } 
     } 

     db.SaveChanges(); 
     return RedirectToAction("Index"); 
    } 
    return View(c); 
}