2011-12-05 69 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); 
}