2009-02-27 42 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的,你应该先把实体,取下,更新,重新将其固定,然后提交。