每个请求缓存实体框架DbContexts

时间:2011-07-05 09:50:32

标签: c# asp.net entity-framework

我有几个基于System.Entity.Data.DbContext的类。它们在Web应用程序的不同端部被多次使用请求 - 实例化它们是否昂贵?

我在HttpContext.Current.Items中缓存了它们的副本,因为每个请求都有几个副本它们感觉不对,但我现在发现它不会从HttpContext自动处理掉请求结束。在我开始编写代码来处理它之前(在Application_EndRequest中),我认为我已经重新考虑了这种情况,因为如果我应该在需要它们的地方实例化它们并在那里处理它们,那么它们就没有任何缓存它们。

互联网上已经提出了与此类似的问题,但我似乎无法找到一个完全回答我的问题的问题。对不起,如果我在重复某人。

更新

我发现在this博客文章中处理上下文可能并不重要,但我仍然有兴趣听到它们首先实例化是否代价高昂。基本上,幕后有很多EF魔法,我想避免经常这样做吗?

4 个答案:

答案 0 :(得分:6)

最好的办法是使用IoC容器来管理生命周期 - 他们非常非常擅长这一点,这是一种非常常见的情况。具有使动态调用变得容易的附加优势 - 意味着对样式表的请求不会创建DB上下文,因为它在BeginRequest()中是硬编码的。

答案 1 :(得分:4)

我正在回答我自己的问题是否完整。

This回答提供了有关此问题的更多信息。

总之,实例化DbContext并不昂贵,所以不用担心。

此外,您也不必担心处置数据上下文。您可能会注意到ScottGu不在他的样本中(他通常将上下文作为控制器上的私有字段)。 This回答有一些关于处理数据上下文的Linq到SQL团队的一些很好的信息,this博客文章也扩展了这个主题。

答案 2 :(得分:3)

使用HttpContext.Items并在EndRequest中手动处理您的上下文 - 您甚至可以为此创建自定义HTTP模块。这是正确的处理。上下文处理还将释放对所有被跟踪实体的引用,并允许GC收集它们。

如果您确实需要,可以为每个请求使用多个上下文,但在大多数情况下,只需一个即可。如果您的服务器处理是一个逻辑操作,您应该为整个工作单元使用一个上下文。如果您在事务中进行更多更改,这一点尤为重要,因为在多个上下文中,您的事务将被提升为分布式,并且会对性能产生负面影响。

答案 3 :(得分:0)

我们有一个使用与您描述的模式相似的模式的Web项目(尽管有多个独立的L2S上下文而不是EF)。虽然上下文没有放在请求的末尾,但是我们发现因为HttpContext.Current变得没有引用,GC会在适当的时候收集上下文,导致在场景下进行置换。我们使用内存分析器确认了这一点。虽然上下文的持续时间比应有的长,但我们可以接受。

由于注意到这种行为,我们尝试了几种替代方案,包括在EndRequest上处理上下文,并强制在EndRequest上进行GC收集(这不是我的想法并且很快就退去了)。

我们现在正在调查实施工作单元模式的可能性,该模式包含我们在请求期间收集的上下文。有一些很棒的文章,如果你谷歌它,但对我们来说,唉,实施所需的时间超过了潜在的好处。

另一方面,我现在正在研究转向结合SOA /工作单元方法的复杂性,但同样,在没有知识的情况下构建企业规模的应用程序之后,事后的事情就是其中之一。

我很想听听别人对这个问题的看法。