FineUI 官方论坛

标题: AppBoxContext DB不用每次都using, 方法着实精妙 [打印本页]

作者: ylxin2014    时间: 2015-2-13 01:20
标题: AppBoxContext DB不用每次都using, 方法着实精妙
分享一下: 原博客地址: 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.

作者: sanshi    时间: 2015-2-14 12:23
的确是这样,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 官方论坛 (https://fineui.com/bbs/) Powered by Discuz! X3.4