Asp.net

EF 是否在 DbContext 的不同實例之間記憶體實體?

  • June 11, 2013

在 Asp.net 中為每個查詢創建 DbContext 是否會使 EF 僅從其記憶體中讀取數據,還是每次都查詢整個集合的 DB?我知道每個 AppDomain 的元數據記憶體,但是數據呢?

上下文:具有 MVC4 + Web API 前端的數據採集和視覺化應用程序,不會稱其為“大容量”,但許多查詢會在更短的時間內返回相同的數據集。

Entity Framework 沒有每個 AppDomain 的數據記憶體,每個上下文實例只有一個記憶體。

如果您為每個請求或查詢創建一個新上下文,您將從一個空記憶體開始,EF 將從數據庫中獲取數據。

此外,術語“每個上下文實例記憶體”可能會產生誤導,因為這並不意味著如果實體已載入到上下文記憶體中,EF 將不會對數據庫執行查詢。此記憶體的工作方式以及如何利用(或不利用)它如下:

  • DbSet<T>在 a 上或通常在 an上的每個LINQ-to-Entities 查詢IQueryable<T>都將執行數據庫查詢,無論實體是否已存在於上下文中。但是,如果上下文中已經存在與查詢實體具有相同鍵的實體,EF 將丟棄該查詢的結果並將記憶體的實體實例返回給呼叫者。

它會在執行查詢後檢查是否存在具有相同鍵的實體。(對於復雜的查詢——例如包含一個的查詢Include——它之前不能做這個檢查,因為它不知道將返回哪些實體和鍵值。)

這是預設行為(MergeOptionis AppendOnly)。我相信您可以將此行為更改為OverwriteChanges和其他選項,但它們都不會避免 LINQ 查詢總是發出數據庫查詢。

  • 要僅通過鍵查詢實體,您可以使用GetObjectByKeyor Find(with DbContext) 它將首先檢查具有該鍵的實體是否已記憶體在上下文中,然後返回此記憶體對象。如果不是,它將執行數據庫查詢來載入它。
  • 您可以查詢 EF 的 ChangeTracker,它特別受支持,您可以通過集合DbContext訪問上下文記憶體。DbSet<T>.Local

這裡的問題是,如果查詢Local不返回結果,則沒有自動查詢數據庫的邏輯。您必須手動編寫此邏輯。更大的問題是查詢Local是 LINQ-to-Objects 而不是 LINQ-to-Entities (Local不實現IQueryable<T>,僅IEnumerable<T>),因此您經常需要重寫查詢以執行操作Local- 例如您不能使用Include在這裡,你不能使用 any EntityFunctions,你會在區分大小寫等方面得到不同的字元串比較行為。

引用自:https://stackoverflow.com/questions/17042697