2011-09-22 104 views
4

我正在使用EF和Code First的ASP.NET MVC3。DBContext,狀態和原始值

我正在爲練習寫一個簡單的問題跟蹤器。在我的控制器我有一個代碼相當標準位:

[HttpPost] 
public ActionResult Edit(Issue issue) { 
    if (ModelState.IsValid) { 
     dbContext.Entry(issue).State = EntityState.Modified 
     ..... 
    } 
} 

問題第1部分 我試圖讓我的頭周圍的DbContext如何工作 - 之前,我給自己定了國家對dbContext.Entry (問題),我認爲我的問題對象是分離的。一旦我設置了要修改的狀態,該對象就會被附加 - 但是是什麼? dbContext或數據庫?我有點想念這(附加)實際上是什麼意思?

問題第2部分 出於參數的緣故,假設我決定在我的問題上設置「接受」字段。 Accepted是一個布爾值。我從錯誤開始,我將其設置爲true並提交。在我的對象被附加的時候,OriginalValues集合有什麼意義?例如,如果我設置的設置EntityState.Modified但在此之前我所說的SaveChanges()我可以查詢

db.Entry(issue).OriginalValues["Accepted"] 

,這會給我相同的值,簡單地查詢已到已通過發行對象剛過斷點編輯....即它給了相同的結果

issue.Accepted 

我清楚地失去了一些東西,因爲文件說 「原來的值通常是實體的屬性值,因爲他們當從數據庫中查詢最後一次。」 但事實並非如此,因爲數據庫仍在報告Accepted爲false(是的,我在文檔中註明了「通常」一詞,但我的代碼幾乎都是由MS代碼生成的標準,所以....)。 那麼,我錯過了什麼?這裏究竟發生了什麼?

回答

3

上下文只能與附加實體一起使用。附件意味着上下文知道該實體,它可以保留其數據,並且在某些情況下可以提供更改跟蹤或延遲加載等高級功能。

默認情況下,由上下文實例從數據庫加載的所有實體都附加到該實例。在Web應用程序和其他斷開連接的情況下,每個已處理的HTTP請求都有一個新的上下文實例(如果你不這樣做,你會犯很大的錯誤)。此外,由HTTP POST中的模型綁定器創建的實體不會被該上下文加載 - 它是分離的。如果你想堅持這個實體,你必須附加它並告知上下文關於你所做的改變。將狀態設置爲EntryModified將執行這兩種操作 - 它會將實體附加到上下文並將其全局狀態設置爲Modified,這意味着當您撥打SaveChanges時,將會更新所有標量和複雜屬性。

因此,通過將狀態設置爲Modified,您已將實體附加到上下文,但在調用SaveChanges之前,它不會影響您的數據庫。

OriginalValues在完全連接的情況下非常有用,您從數據庫加載實體並對該連接實體進行更改。在這種情況下,OriginalValues顯示從數據庫加載的屬性值,CurrentValues顯示由應用程序設置的實際值。在你的場景中,上下文不知道原始值。它認爲原始值是您附加實體時使用的值。