2011-05-25 123 views
9

我想使用實體框架來查詢數據庫,我有以下代碼,我用來獲取一些數據。刷新數據使用實體框架

var students= MyEntities.Students.Where(s => s.Age > 20).ToList(); 

此代碼正常工作並返回正確的數據。但是,如果我運行此代碼,然後轉到數據庫並更新記錄以更改此代碼應返回的數據,然後重新運行此代碼而不關閉應用程序,我將獲取原始數據。 我很確定它用於正常工作,但現在這不刷新數據。

回答

16

不,它從來沒有工作。這是實體框架(和許多ORM工具)稱爲標識映射(explanation here)的基本行爲。

如果您在相同的上下文中運行查詢,則不會更新您的實體。它只會追加運行這兩個查詢之間在數據庫中創建的新實體。如果要強制EF重新加載實體必須做這樣的事情:

ObjectQuery query = MyEntities.Students; 
query.MergeOption = MergeOption.OverwriteChanges; 
var students = query.Where(s => s.Age > 20).ToList(); 
+0

如果你只是查詢你應該使用'MergeOption.NoTracking'?這將強制查詢命中數據庫。 – Nix 2011-05-25 15:32:20

+0

無論如何查詢都會碰到DB。我不確定當你使用'NoTracking'時會發生什麼,並且你已經在「緩存」中有實體,因爲當使用延遲加載時EF仍然保留它們。 – 2011-05-25 15:34:33

+0

這似乎是做我想做的事情。使用Refresh()方法也可以,但我認爲使用ObjectQuery是一個更乾淨的解決方案。標記爲答案。然而,Nix在使用EF時提供了一個很好的關於最佳實踐的觀點,這對了解更多信息是很好的,所以我需要更多地瞭解這一點。 – chiefanov 2011-05-25 16:38:41

6

由於EF會緩存數據,所以如果數據在幕後更改,並且您不處理/重新打開上下文,則會遇到問題。

一般的經驗法則是保持上下文的生命週期儘可能短,以避免像剛剛提到的問題。

請不要忽視我上面所說的內容,但是如果您想強制從數據庫刷新,可以使用Refresh()方法。

+0

注意,刷新正在做許多查詢,以更大的數據集,除了可能會或可能不會被執行的實際查詢,而query.MergeOption是隻是迫使查詢從數據庫中讀取 – 2013-12-05 00:05:10