實體框架和連接池
我最近開始在我的 .NET 4.0 應用程序中使用 Entity Framework 4.0,並對與池相關的一些事情感到好奇。
- 據我所知,連接池由 ADO.NET 數據提供程序管理,在我的例子中是 MS SQL 伺服器。當您實例化一個新的實體上下文 (
ObjectContext) 時,這是否適用,即無參數new MyDatabaseModelEntities()?- a)為應用程序創建一個全域實體上下文(即一個靜態實例)或b)為每個給定的操作/方法創建和公開一個實體上下文的優點和缺點是什麼,使用一個
using塊。- 對於某些場景,我應該了解的任何其他建議、最佳實踐或常用方法?
- 連接池的處理方式與任何其他 ADO.NET 應用程序一樣。實體連接仍然使用傳統的數據庫連接和傳統的連接字元串。我相信如果您不想使用它,可以關閉連接字元串中的連接池。(閱讀有關SQL Server 連接池 (ADO.NET)的更多資訊)
- 永遠不要使用全域上下文。ObjectContext 在內部實現了幾種模式,包括身份映射和工作單元。使用全域上下文的影響因應用程序類型而異。
- 對於 Web 應用程序,每個請求使用單個上下文。對於 Web 服務,每次呼叫使用單個上下文。在 WinForms 或 WPF 應用程序中,每個表單或每個展示者使用單個上下文。可能有一些特殊要求不允許使用這種方法,但在大多數情況下這已經足夠了。
如果您想了解 WPF/WinForm 應用程序的單個對像上下文有什麼影響,請查看這篇文章。這是關於 NHibernate Session 但想法是一樣的。
編輯:
當您使用 EF 時,預設情況下每個上下文僅載入每個實體一次。第一個查詢創建實體實例並將其儲存在內部。任何需要具有相同鍵的實體的後續查詢都會返回此儲存的實例。如果數據儲存中的值發生更改,您仍會收到帶有初始查詢值的實體。這稱為身份映射模式。您可以強制對像上下文重新載入實體,但它會重新載入單個共享實例。
SaveChanges在呼叫上下文之前,對實體所做的任何更改都不會保留。您可以對多個實體進行更改並一次儲存它們。這稱為工作單元模式。您不能有選擇地說出要保存哪個修改後的附加實體。結合這兩種模式,你會看到一些有趣的效果。整個應用程序只有一個實體實例。即使更改尚未持久化(送出),對實體的任何更改也會影響整個應用程序。在大多數情況下,這不是您想要的。假設您在 WPF 應用程序中有一個編輯表單。您正在使用實體並決定取消複雜的編輯(更改值、添加相關實體、刪除其他相關實體等)。但是實體已經在共享上下文中進行了修改。你會怎麼做?提示:我不知道任何 CancelChanges 或 UndoChanges on
ObjectContext.我認為我們不必討論伺服器場景。簡單地在多個 HTTP 請求或 Web 服務呼叫之間共享單個實體會使您的應用程序毫無用處。任何請求都可以觸發
SaveChanges並保存來自另一個請求的部分數據,因為您在所有請求之間共享單個工作單元。這也會帶來另一個問題——上下文以及對上下文中實體的任何操作或上下文使用的數據庫連接都不是執行緒安全的。即使對於只讀應用程序,全域上下文也不是一個好的選擇,因為您可能每次查詢應用程序時都需要新數據。