2014-03-27 189 views
1

當我使用實體框架它創建對象爲數據庫中的所有數據例如context.Customers.Load();它會創建1000個客戶對象,然後5000訂單對象,如果是這樣,它不會使用很多記憶?c#實體框架加載實體

回答

2

您應該從您需要的時刻創建EF上下文,並從您完成的那一刻開始處理它(工作單元,using語句)。當然,你應該只查詢你需要的東西 - 我懷疑你在一個請求中需要5000個訂單。

是的,EF爲每個查詢創建實體。導航屬性沒有加載,你必須專門包含這些或使用延遲加載(但我會避免這種情況)。

+0

第一MSDN上:「當的Windows Presentation Foundation(WPF)或Windows窗體的工作,每使用形式的上下文實例,就可以使用更改跟蹤功能這方面提供了」,所以我使用WPF,和什麼如果我需要所有客戶的列表(DataGrid)或訂單 – Lerner

+0

然後確保您的問題包含足夠的信息,我們無法猜測。對我而言,您的WPF應用程序直接訪問數據庫聽起來很詭異。即使那樣,你也不需要5000個訂單。 –

+0

嗨,它不是數字5000,我想知道的是,如果EF在表中查詢我創建的表中的每個原料的內存對象,並且你沒有回答我,如果我需要一個所有客戶的列表是什麼?謝謝 – Lerner

1

除了L-Three的回覆之外,使用using聲明可能不適合所有情況。例如,對於桌面應用程序,保持連接打開而不是始終打開和關閉連接以查詢簡單數據更有意義。確保在完成時處理它很重要。一個好的地方是聽窗口上的Closing事件。觸發時,您可以處置DbContext

如果您不縮小查詢的範圍,例如:使用where子句,EF會在嘗試訪問數據庫時加載數據庫中的所有對象。通過執行var query = Db.Users;,您實際上並未查詢數據庫,您只是創建了一條查詢,當您嘗試訪問數據時將發送該查詢。如果你做了var query = Db.User.ToList();,那麼是的,查詢將被執行,並且所有User對象將被查詢,映射並返回。所以如果你有100萬行,EF會嘗試加載100萬條記錄。在大多數情況下,沒有理由返回數據庫中的所有對象,但始終存在邊緣案例。

取決於您如何配置上下文,子女關係有點不同。默認情況下,我相信EF使用了一種叫做的延遲加載延遲加載允許EF用特殊代碼覆蓋您的屬性,直到您嘗試訪問它們時纔會加載子對象。在另一方面,你可以做什麼叫做急切加載。這使您可以在查詢中包含所有子對象,從而減少訪問數據庫的次數。在大多數情況下,應該使用急切加載,因爲您應該知道應用程序將顯示給用戶的信息。

如果你只曾經使用延遲加載你可以得到一些麻煩,因爲它只是工作,它可以通過一些簡單的創建N + 1周的語句會導致性能問題的道路。

+0

因此,如果我想要列表框中的客戶列表,並且比用戶選擇客戶時顯示該客戶的訂單datagrid(例如QuickBooks有一個所有事務的列表)EF會爲每個訂單在內存中創建對象嗎?!這是不是內存使用問題? – Lerner

+0

是的,EF會加載所有的客戶,並會記錄它在內存中的變化。當您訪問客戶對象的導航屬性時,它會將這些屬性加載到內存中,並跟蹤對這些內容的更改。它**可能會成爲一個內存使用問題,具體取決於返回的實體數量和隨後的對象圖形。還有加載時間的問題。 – Justin

+0

當我選擇第二個客戶時,第一個客戶的訂單是否會被垃圾收集? – Lerner