這是一個非常好的問題。默認情況下,我發現只要啓用了更改跟蹤(這是默認情況下除非關閉),Entity Framework將會很好地向數據庫應用您要求更改的內容。
因此,如果您只改變對象的1個字段,然後調用SaveChanges(),EF只會在調用SaveChanges()時更新該字段。
這裏的問題是,當您將視圖模型映射到實體對象時,所有的值都會被覆蓋。這裏是我的處理是這樣的:
在這個例子中,有一個名爲的人一個單一的實體:
Person
======
Id - int
FirstName - varchar
Surname - varchar
Dob - smalldatetime
現在讓我們說,我們要創建一個將只更新杜伯視圖模型,並留下所有其他領域究竟如何,這是我如何做到這一點。
首先,創建一個視圖模型:
public class PersonDobVm
{
public int Id { get; set; }
public DateTime Dob { get; set; }
public void MapToModel(Person p)
{
p.Dob = Dob;
}
}
現在寫的代碼大致如下(你必須改變它來匹配您的上下文的名稱等):
DataContext db = new DataContext();
Person p = db.People.FirstOrDefault();
// you would have this posted in, but we are creating it here just for illustration
var vm = new PersonDobVm
{
Id = p.Id, // the Id you want to update
Dob = new DateTime(2015, 1, 1) // the new DOB for that row
};
vm.MapToModel(p);
db.SaveChanges();
的MapToModel方法可能會更復雜,並在將視圖模型字段分配給實體對象之前執行各種附加檢查。
無論如何,當調用SaveChanges結果是下面的SQL:
exec sp_executesql N'UPDATE [dbo].[Person]
SET [Dob] = @0
WHERE ([Id] = @1)
',N'@0 datetime2(7),@1 int',@0='2015-01-01 00:00:00',@1=1
所以,你可以清楚地看到,實體框架並沒有試圖更新任何其他領域 - 只是杜伯領域。
我知道你的例子中你想避免用手來編碼每個任務,但我認爲這是最好的方法。你把它全部放在你的虛擬機中,這樣它就不會拋棄你的主代碼,這樣你就可以滿足特定的需求(即那裏的複合類型,數據驗證等)。另一種選擇是使用AutoMapper,但我不認爲它們是安全的。如果您在虛擬機中使用AutoMapper並將「Dob」拼寫爲「Doob」,則它不會將「Doob」映射到「Dob」,也不會告訴您!它會默默地失敗,用戶會認爲一切正常,但變化不會被保存。如果你在虛擬機中拼寫「Dob」爲「Doob」,編譯器會提醒你MapToModel()引用了「Dob」,但你的虛擬機中只有一個名爲「Doob」的屬性。
我希望這可以幫助你。
創建視圖模型..只添加你想要的領域..設定值 – JamieD77
即使我創建視圖模型;更新到我的表「Person」時仍存在同樣的問題。如果我缺少一些東西,請糾正我的問題 –
您的viewmodel是否只顯示了您顯示的25個字段? – JamieD77