ASP.NET MVC中每个请求一个DbContext(没有IOC容器)如何处理?

内容来源于 Stack Overflow,并遵循CC BY-SA 3.0许可协议进行翻译与使用

  • 回答 (2)
  • 关注 (0)
  • 查看 (24)

如果不使用IOC容器,如何保证每个请求的一个实体框架DbContext?

看起来大多数解决方案都嵌入到HttpContext.Current.Items字典中,但是如何在请求完成时保证处理DbContext?(或者对于EF来说不是绝对必要的处置DbContext?)

我目前在我的控制器中实例化和配置我的DbContext,但我也在ActionFilters和我的MembershipProvider中有几个单独的实例(我刚刚注意到,也是一对验证器)。所以,我认为集中实例化和存储我的DbContext以减少开销可能是一个好主意。

提问于
用户回答回答于

我会使用BeginRequest / EndRequest方法,这有助于确保在请求结束时正确处理上下文。

protected virtual void Application_BeginRequest()
{
    HttpContext.Current.Items["_EntityContext"] = new EntityContext();
}

protected virtual void Application_EndRequest()
{
    var entityContext = HttpContext.Current.Items["_EntityContext"] as EntityContext;
    if (entityContext != null)
        entityContext.Dispose();
}

并在EntityContext类...

public class EntityContext
{
    public static EntityContext Current
    {
        get { return HttpContext.Current.Items["_EntityContext"] as EntityContext; }
    }
}
用户回答回答于

我知道这不是最近的问题,但我会发布我的答案,因为我相信有人可能会觉得它有用。

正如其他许多人一样,我遵循了接受答案中提到的步骤。耶,它的作品。但是,有一个问题:

方法BeginRequest()和EndRequest()每次发出请求时都会触发,但不仅适用于aspx页面,而且适用于所有静态内容!也就是说,如果你使用上面提到的代码,并且你的页面上有30个图像,那么你将重新实例化你的dbcontext 30次!

对此的解决方案是使用包装类来检索上下文,如下所示:

internal static class ContextPerRequest
{
      internal static DB1Entities Current
      {
          get
          {
              if (!HttpContext.Current.Items.Contains("myContext"))
              {
                  HttpContext.Current.Items.Add("myContext", new DB1Entities());
              }
              return HttpContext.Current.Items["myContext"] as DB1Entities;
          }
      }
 }

然后处理

protected void Application_EndRequest(object sender, EventArgs e)
{
   var entityContext = HttpContext.Current.Items["myContext"] as DB1Entities;
   if (entityContext != null) 
      entityContext.Dispose();
}

此修改可确保仅在每个请求中实例化和处理您的上下文,并且仅在需要时才处理。选定的答案每次都会实例化上下文。

注意: DB1Entities来自DbContext(由VS生成)。你可能想用你的上下文名称来改变它;)

注2:在这个例子中,我正在使用一个dbcontext。如果你需要使用多个,你需要根据你的需要修改这些代码。不要把这看作是世界问题的最终解决方案,因为它当然不是最终产品。它只是为了提供一个提示,它是如何以非常简单的方式实现的。

注3:同样的方法也可以用于不同的情况,例如当你想共享一个SqlConnection实例或其他任何......这个解决方案不是排他性的DbContext对象,也不是实体框架。

扫码关注云+社区