在HTTP中缓存单个EF 6 DBContext会引起问题吗?

本文关键字:问题 DBContext HTTP 缓存 单个 EF | 更新日期: 2023-09-27 18:03:09

我正在研究一个项目,在这个项目中,我们对是否在HTTP请求中缓存EF 6 DBContext存在冲突。

对于每个HTTP请求,我们实例化多个类,并且可以在每个类上调用多个方法。

是每个类实例一个DBContext实例最好,还是可以在HTTPContext中缓存一个DBContext。缓存吗?

其他因素:

  • 我倾向于每个类一个DBContext,但其他人担心"新DBContext"的成本

  • 我们不使用IoC/DI-container

  • 一些相关的答案是2010年的,我想确保它们是相关的

在HTTP中缓存单个EF 6 DBContext会引起问题吗?

不要在请求之间缓存上下文实例。它们被设计成在小范围内使用和处理。缓存的上下文会"泄漏"(或者更确切地说,消耗越来越多的)内存,因为它会从应用程序的所有查询和提交中积累所有更改跟踪数据。

当使用Web应用程序时,每个请求使用一个上下文实例。

同一文档还提到:

上下文不是线程安全的。只要同一个实体类的一个实例没有同时被多个上下文跟踪,你仍然可以创建一个多线程应用程序。

这完全排除了共享上下文,因为请求是由ThreadPool的多个线程提供服务的。

下面是你如何在MVC应用中实现每个请求共享上下文:

Global.asax:

public class MvcApplication : System.Web.HttpApplication
{
    public const string dbcontext = "Db.Context";
    public MvcApplication()
    {
        BeginRequest += MvcApplication_BeginRequest;
        EndRequest += MvcApplication_EndRequest;
    }
    void MvcApplication_BeginRequest(object sender, EventArgs e)
    {
        HttpContext.Current.Items[dbcontext] = new BlahContext();
    }
    void MvcApplication_EndRequest(object sender, EventArgs e)
    {
        var ctx = HttpContext.Current.Items[dbcontext] as BlahContext;
        if (ctx != null)
            try
            {
                (ctx as IDisposable).Dispose();
            }
            catch (ObjectDisposedException)
            {
                //yum
            }
    }
}