EntityFramework系列(三)---上下文线程内唯一

为什么要让DbContext线程内唯一

  在使用EF的情况下,我们通常把SaveChange这个方法提到业务逻辑层,如果在用到DbContext的时候就new一个出来的话,不能保证同一个业务逻辑使用的是同一个上下文对象,不同的DbContext就不能对实体状态进行有效的追踪,可能造成数据混乱,一些EF对象获得的数据可能已经被其他EF对象改变过,这就造成脏读。

  使用单例模式可以有效避免脏读的问题,但是DbContext对象不能被有效的释放,如果无数请求使用同一个DbContext,这个DbContext对象容器就要追踪无数个实体的状态,内存压力很大。保证在线程内对象唯一,对于每一个请求使用同一个上下文是一种折中的方法。通过微软ASP机制线程相关的HttpContext对象以及CallContext对象。

  CallContext 的概念:是类似于方法调用的线程本地存储区的专用集合对象,并提供对每个逻辑执行线程都唯一的数据槽。数据槽不在其他逻辑线程上的调用上下文之间共享。当 CallContext 沿执行代码路径往返传播并且由该路径中的各个对象检查时,可将对象添加到其中。也就是说,当前线程对对象进行储存到线程本地储存区,对象随着线程的销毁而销毁。

使用DbContext的代码如下

 1   public class DbFactory
 2     {
 3          //callContext实现dbcontext唯一
 4          public static DbContext GetDbContext()
 5          {
 6              DbContext _context = CallContext.GetData("dbContext") as DbContext;
 7              if (_context == null)
 8              {
 9                   _context = new MyEntities();
10                  CallContext.SetData("dbContext", _context);
11              }
12              return _context;
13          }
14 
15          //在web环境下,在web环境下
16          //CallContext.HostContext as HttpContext==HttpContext.Current,线程不安全时可能为空,因此推荐第一种方式
17          public static DbContext GetDbContext2()
18          {
19              DbContext _context=HttpContext.Current.Items["dbContext"] as DbContext;
20              if (_context == null)
21              {
22                  _context = new MyEntities();
23                  HttpContext.Current.Items["dbContext"]=_context;
24              }
25              return _context;
26          }
27     }

猜你喜欢

转载自www.cnblogs.com/wyy1234/p/9070780.html