2009-02-27 58 views
2

我正在設計可以接收對象的ASP.NET MVC應用程序中的表單。下面是一個典型編輯動作的樣子:更新來自表單的LINQ模型的最佳方式

[AcceptVerbs(HttpVerbs.Post)] 
    public ActionResult Edit(int id, Person person) 
    { 
     peopleService.SavePerson(person); 
     return Redirect("~/People/Index"); 
    } 

SavePerson呼叫服務做到這一點:

public void SavePerson(Person person) 
    { 
     _peopleRepository.SavePerson(person); 
    } 

而且SavePerson調用存儲庫中的做到這​​一點:

public void SavePerson(Person person) 
    { 
     using (var dc = new SIGAPDataContext()) 
     { 
      if (person.IsNew) 
      { 
       dc.People.InsertOnSubmit(person); 
      } 
      else 
      { 
       dc.People.Attach(person, true); 
      } 

      dc.SubmitChanges(); 
     } 
    } 

現在,這在我創建新記錄時效果很好。但是,當我更新它沒有所有的表單元素時,它會刪除其他字段。例如,我的Person模型有一個NationalityID屬性,如果它沒有顯示在編輯表單上,則該屬性爲空。

什麼是最好的做法,使模型更新只是來自表單的字段?我必須首先從數據庫中的記錄和更新手動的屬性,如:

Person persistedPerson = peopleService.GetPerson(person.ID); 
persistedPerson.Name = person.Name; 
persistedPerson.DateOfBirth = person.DateOfBirth 
// etc... 

或有任何其他的,更清潔的方式做到這一點?

回答

1

在你的控制,從庫中獲取現有的人,那麼使用的UpdateModel/TryUpdateModel並傳入要更新性質的白名單。這將在控制器上使用ValueProvider,因此不需要在操作參數列表中使用Person對象。

public ActionResult Edit(int id) 
{ 
     Person person = peopleService.GetPerson(id); 
     UpdateModel(person,new string[] { list of properties to update }); 
     peopleService.SavePerson(person); 

     ... 
} 
+0

現在我只需要如何使用UpdateModel在窗體上使用嵌套實體。非常感謝! – changelog 2009-02-27 18:12:52

2

Stephen Walther剛剛在ASP.NET MVC中發佈了an article describing this very thing。我建議你實際上是在LINQ的頂部到SQL創建自己的一套DTO的和業務對象和治療的LINQ to SQL爲language-integrated object database由於gross complexities introduced by managing the DataContext,而根據Pro LINQ,應該通過設計來維持生命儘可能少。

如果你要使用你的LINQ to SQL實體作爲DTO的,你應該先把實體,取下,更新,重新將其固定,然後提交。