2011-07-05 35 views
5

我有幾個基於System.Entity.Data.DbContext的類。他們在Web應用程序的不同端使用了多次請求 - 實例化它們是否昂貴?每個請求緩存實體框架DbContexts

我在HttpContext.Current.Items中緩存了它們的副本,因爲它不適合每個請求擁有它們的多個副本,但是現在我發現它不會自動從HttpContext在請求結束時。在我開始編寫代碼來處理它(在Application_EndRequest中)之前,我認爲我會重新編寫這種情況,因爲如果我只是在需要的地方實例化它們,然後將它們放在那裏,那麼就沒有必要緩存它們。

在互聯網上已經問過類似這樣的問題,但我似乎無法找到完全解答我的問題的問題。對不起,如果我重複某人。

更新

我已經發現了上下文的配置可能不會在this博客文章沒關係,但我仍然有興趣聽他們是否在第一時間實例昂貴。基本上,有很多EF魔術在幕後進行,我想避免太頻繁地做這些事情?

+0

另一個SO回答基本上回答了我的問題:[here](http://stackoverflow.com/questions/813457/instantiating-a-context-in-linq-to-entities)。爲了加快創建速度,儘管可以根據[this](http://stackoverflow.com/questions/2575485/managing-entityconnection-lifetime)問題使用緩存的EntityConnection(儘管它有用介意它不是線程安全的)。我還不能回答我自己的問題,所以我會等着看是否還有其他候選人。 – stewartml

+0

可能重複[一個DbContext每個Web請求...爲什麼?](http://stackoverflow.com/questions/10585478/one-dbcontext-per-web-request-why) – Steven

回答

4

我正在回答我自己的問題的完整性。

This答案提供了有關此問題的更多信息。

總之,實例化DbContext並不昂貴,所以不用擔心。

此外,您也不必擔心處置數據上下文。您可能會注意到ScottGu並沒有在他的樣本中(他通常將上下文作爲控制器上的私人領域)。 This答案從Linq到SQL團隊提供了關於處理數據上下文的一些很好的信息,並且this博客文章也擴展了這個主題。

+0

+1爲良好的鏈接。謝謝 – MLH

0

我們有一個web項目,使用與您所描述的類似的模式(雖然有多個獨立的L2S上下文而不是EF)。雖然上下文沒有在請求的末尾處理,但我們發現由於HttpContext.Current變爲未引用,GC會在適當的時候收集上下文,導致在場景下處理。我們使用內存分析器確認了這一點。儘管情況持續了一段時間,但它對我們來說是可以接受的。

由於注意到我們已經嘗試了兩種替代方法,包括在EndRequest上配置上下文,並強制在EndRequest上收集GC(這不是我的想法並很快退出)。

我們現在正在研究在請求期間實現工作單元模式的可能性,該模式包含我們收集的上下文。有一些關於如果你谷歌它的偉大的文章,但對我們來說,唉,實施所需的時間超過潛在的好處。另一方面,我現在正在研究轉向組合SOA /工作單元方法的複雜性,但同樣的,這是在沒有知識的情況下構建企業級應用程序之後,事後看來讓你感到困惑的事情之一。

我很想聽聽其他民衆對這個問題的看法。

+0

謝謝。我曾想過讓GC在某些時候做這件事在重負荷下不會很好,並且確定性會更好,但我會第一個承認我對這方面的知識不多。我不會做GC.Collect,雖然,請參閱[this](http://stackoverflow.com/questions/2482220/attaching-linq-to-sql-datacontext-to-httpcontext-in-business-layer/2491698# 2491698)回答更好的解決方案。我認爲你認爲緩存上下文是值得的嗎? – stewartml

+0

我認爲這有一條非常模糊的線條。簡單地說,由於我們的應用程序的結構,對於上下文來說,除了單例模式(在HttpContext中實現爲工廠存儲上下文)之外的任何東西都會成爲我們的夜生活 - 必須確保實體已加載到相關上下文中,確保上下文具有在使用延遲加載屬性時未被處置。我們確實有一個_incident_,因此我們在每個請求期間生成了大約15個以上的上下文,可能類似於不緩存上下文。結果導致了顯着的性能下降。 – Smudge202

+0

這裏有一個有趣的[post](http://stephenwalther.com/blog/archive/2008/08/20/asp-net-mvc-tip-34-dispose-of-your-datacontext-or-don-t。 aspx)我只是偶然發現,可能適用於你。我認爲同樣適用於EF上下文 - 基本上,SQL連接無論如何都將被關閉,所以不必擔心處理上下文。 – stewartml

3

使用HttpContext.Items並在EndRequest中手動配置您的上下文 - 您甚至可以爲此創建自定義HTTP模塊。這是一個正確的處理。上下文處理還將釋放對所有跟蹤實體的引用,並允許GC收集它們。

如果您真的需要它們,您可以針對每個請求使用多個上下文,但在大多數情況下,就足夠了。如果你的服務器處理是一個邏輯操作,你應該爲整個工作單元使用一個上下文。如果您在交易中進行更多更改,這一點尤其重要,因爲在多個上下文中,您的交易將被提升爲分佈式,並且會對性能產生負面影響。

+0

謝謝。我不明白「你的交易將被推銷給分銷商」這個問題,請你澄清一下嗎?你是否需要處理上下文?在更新後的問題中提到的博客文章似乎暗示了另一個問題,並且我注意到Scott Gu傾向於使用私有字段來處理他的上下文,而這些字段不會被處置。 – stewartml

+0

@拉迪斯拉夫的觀點與我們特別相關。我們依靠多個上下文來處理交易範圍,這當然會導致交易通過DTC進行促銷。但是,我們仍然發現實體集合已經被有效地清理了,不需要強制處理上下文。我知道這不是有效的編程或者是最好的做法,但是它只是工作。當我們強制處理上下文時,還有一個奇怪的副作用,那就是應該是同一個上下文的獨立實例,正在使用異步,在我們身上死亡... – Smudge202

6

最好的辦法是在這裏使用IoC容器來管理生命週期 - 它們非常非常擅長,而且這是很常見的情況。具有使動態調用變得簡單的額外優勢 - 意味着對樣式表的請求不會創建數據庫上下文,因爲它在BeginRequest()中進行了硬編碼。

+0

您是否特別推薦? – stewartml

+0

如果我必須選擇一個沒有約束的,我可能會去熟悉結構圖。大多數(如果不是全部的話)「名稱」容器都具有此功能。 –

+0

+1爲StructureMap(適合我們) – RPM1984