FineUI 官方论坛

 找回密码
 立即注册

QQ登录

只需一步,快速开始

本论坛已关闭(禁止注册、发帖和回复)
请移步 三石和他的朋友们

FineUI首页 WebForms - MVC & Core - JavaScript 常见问题 - QQ群 - 十周年征文活动

FineUI(开源版) 下载源代码 - 下载空项目 - 获取ExtJS - 文档 在线示例 - 版本更新 - 捐赠作者 - 教程

升级到 ASP.NET Core 3.1,快、快、快! 全新ASP.NET Core,比WebForms还简单! 欢迎加入【三石和他的朋友们】(基础版下载)

搜索
查看: 4096|回复: 1
打印 上一主题 下一主题

AppBoxContext DB不用每次都using, 方法着实精妙

[复制链接]
跳转到指定楼层
楼主
发表于 2015-2-13 01:20:32 | 只看该作者 回帖奖励 |倒序浏览 |阅读模式
分享一下: 原博客地址: http://www.cnblogs.com/sanshi/p/3274427.html

using(var db = new AppBoxContext())
{
// .....
}


但是每次都写using 会觉得很烦,能不能就将AppBoxContext实例存储在一个变量中呢,下面这篇文章给出了最佳实践:
http://stackoverflow.com/questions/6334592/one-dbcontext-per-request-in-asp-net-mvc-without-ioc-container
One DbContext per Request  


最开始的解答:

I would use the BeginRequest/EndRequest method, this helps ensure that your context is disposed of properly when the request is over with.
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();}And in your EntityContext class...
public class EntityContext{    public static EntityContext Current    {        get { return HttpContext.Current.Items["_EntityContext"] as EntityContext; }    }}   

下一个回答指出存在问题,

I know this is not a recent question, but I'll post my answer anyway, because I believe someone may find it useful.
As probably many others, I followed the steps mentioned in the accepted answer. Yay, it works. HOWEVER, there's one catch:
Methods BeginRequest() and EndRequest() fire each time a request is made, but not only for aspx pages, but for ALL STATIC CONTENT! That said, if you use the code mentioned above and you have on your page let's say 30 images, you're re-instantiating your dbcontext 30 times!

新的方案:

The solution for this is to use a wrapping class for retrieving the context, something like this:
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;          }      } }And then for disposing
protected void Application_EndRequest(object sender, EventArgs e){   var entityContext = HttpContext.Current.Items["myContext"] as DB1Entities;   if (entityContext != null)       entityContext.Dispose();}
Note: DB1Entities is derived from DbContext (generated by VS). You would probably want to alter it with your context name ;)
Note 2: in this example I'm working with just one dbcontext. If you need to work with multiple, you would need to modify this code according to your needs. Don't take this as some ultimate solution to world problems, because it certainly isn't a final product. It is meant just to give a hint, how it may be achieved in a very easy way.
Note 3: Same approach can be used in different situations as well, for instance when you'd like to share an instance of SqlConnection or any other... This solution isn't exclusive to DbContext object, nor to Entity framework.
沙发
发表于 2015-2-14 12:23:41 | 只看该作者
的确是这样,AppBox也是这么做的:

在PageBase中:
  1. public static AppBoxProContext DB
  2.         {
  3.             get
  4.             {
  5.                 // http://stackoverflow.com/questions/6334592/one-dbcontext-per-request-in-asp-net-mvc-without-ioc-container
  6.                 if (!HttpContext.Current.Items.Contains("__AppBoxProContext"))
  7.                 {
  8.                     HttpContext.Current.Items["__AppBoxProContext"] = new AppBoxProContext();
  9.                 }
  10.                 return HttpContext.Current.Items["__AppBoxProContext"] as AppBoxProContext;
  11.             }
  12.         }
复制代码

然后在Global.asax.cs 中:
  1. protected virtual void Application_EndRequest()
  2.         {
  3.             var context = HttpContext.Current.Items["__AppBoxProContext"] as AppBoxProContext;
  4.             if (context != null)
  5.             {
  6.                 context.Dispose();
  7.             }
  8.         }
复制代码



您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

小黑屋|FineUI 官方论坛 ( 皖ICP备2021006167号-1 )

GMT+8, 2024-11-22 02:58 , Processed in 0.043580 second(s), 18 queries , Gzip On.

Powered by Discuz! X3.4

© 2001-2017 Comsenz Inc.

快速回复 返回顶部 返回列表