线程共享的DbContext与私有的DbContext

在使用Linq to Sql做为底层ORM时,它为我们提供的数据上下文为DataContext对象,实现上我们通过拖动生成的DBML文件,它们都是继承自 System.Data.Linq.DataContext类型的,所以DataContext就是LINQ数据对象的基类,有时,我们可以通过这种类的多态性来动态创建DB的实例。

创新互联致力于互联网网站建设与网站营销,提供成都网站制作、网站设计、外贸网站建设、网站开发、seo优化、网站排名、互联网营销、成都微信小程序、公众号商城、等建站开发,创新互联网站建设策划专家,为不同类型的客户提供良好的互联网应用定制解决方案,帮助客户在新的全球化互联网环境中保持优势。

在每个DataContext类中,它有几个实例的构造方法,用来让你创建DataContext的实例,如下:

 
 
 
  1. ///   
  2.          /// 使用默认的连接串创建实现(每拖一次数据库,就会产生一个连接串)  
  3.          ///   
  4.          public DataClasses1DataContext() :   
  5.                  base(global::test.Properties.Settings.Default.EEE114ConnectionString, mappingSource)  
  6.          {  
  7.              OnCreated();  
  8.          }  
  9.          ///   
  10.          /// 使用指定的连接串,可能配置在config文件里  
  11.          ///   
  12.          ///   
  13.          public DataClasses1DataContext(string connection) :   
  14.                  base(connection, mappingSource)  
  15.          {  
  16.              OnCreated();  
  17.          }  
  18.          ///   
  19.          /// 使用使用了IDbConnection接口的对象创建实例  
  20.          ///   
  21.          ///   
  22.          public DataClasses1DataContext(System.Data.IDbConnection connection) :   
  23.                  base(connection, mappingSource)  
  24.          {  
  25.              OnCreated();  
  26.          }  
  27.          ///   
  28.          /// 使用连接串和数据库的映射文件来建立实例,mappingSource可能是一个XML文件  
  29.          ///   
  30.          ///   
  31.          ///   
  32.          public DataClasses1DataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :   
  33.                  base(connection, mappingSource)  
  34.          {  
  35.              OnCreated();  
  36.          } 

而我们在实现项目开发中,可能用第二种比较多,即

 
 
 
  1. DataClasses1DataContext db=new LINQ.DataClasses1DataContext(System.Configuration.ConfigurationManager.ConnectionStrings["XXB"].ToString()) 

这样,在开发环境与生成环境只要配置一个CONFIG文件即可。灵活。

而今天的主题是线程共享的DbContext与私有的DbContext,所以开始书归正转了,对于ado.net架构中,我们往往使用一个static全局对象来完成数据访问工作,而在linq to sql中,如果你建立一个static对象,它会出现很多问题,这在实现开发过程中才可以体会到,所以,今天要说的不是static对象。

一 线程共享的DbContext,说清楚一点就是在一个线程内,你的DataContext对象是共享的,是一个对象,不是new出很多个datacontext对象来,这事实上是一种单例模式的体现,这没有问题,它解决了static对象所产生的问题,而又满足了多表关联查询时出现(不能实现不同数据上下文件的引用,linq to sql和Ef都是这样的)的问题。

代码:

datacontext生成工厂:

 
 
 
  1. ///   
  2.      /// 数据库建立工厂  
  3.      /// Created By : 张占岭  
  4.      /// Created Date:2011-10-14  
  5.      /// Modify By:  
  6.      /// Modify Date:  
  7.      /// Modify Reason:  
  8.      ///   
  9.      internal sealed class DbFactory  
  10.      {  
  11.          #region Fields  
  12.          static System.Timers.Timer sysTimer = new System.Timers.Timer(10000);  
  13.          volatile static Dictionary divDataContext = new Dictionary();  
  14.          #endregion  
  15.    
  16.          #region Constructors  
  17.          ///   
  18.          /// 类构造方法  
  19.          ///   
  20.          static DbFactory()  
  21.          {  
  22.              sysTimer.AutoReset = true;  
  23.              sysTimer.Enabled = true;  
  24.              sysTimer.Elapsed += new System.Timers.ElapsedEventHandler(sysTimer_Elapsed);  
  25.              sysTimer.Start();  
  26.          }  
  27.          #endregion  
  28.    
  29.          #region  Static Methods  
  30.    
  31.          ///   
  32.          /// 订阅Elapsed事件的方法  
  33.          ///   
  34.          ///   
  35.          ///   
  36.          static void sysTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)  
  37.          {  
  38.              List list = divDataContext.Keys.Where(item => item.ThreadState == ThreadState.Stopped).ToList();  
  39.              for (int index = 0; index < list.Count; index++)  
  40.              {  
  41.                  for (int refer = 0; refer < divDataContext[list[index]].Length; refer++)  
  42.                      if (divDataContext[list[index]][refer] != null)  
  43.                      {  
  44.                          divDataContext[list[index]][refer].Dispose();  
  45.                          divDataContext[list[index]][refer] = null;  
  46.                      }  
  47.                  divDataContext.Remove(list[index]);  
  48.                  list[index] = null;  
  49.              }  
  50.          }  
  51.          ///   
  52.          /// 通过工厂的制造模式获取相应的LINQ数据库连接对象  
  53.          ///   
  54.          /// 数据库名称(需要与真实数据库名称保持一致)  
  55.          /// LINQ数据库连接对象  
  56.          public static DbContext Intance(string dbName)  
  57.          {  
  58.              return Intance(dbName, Thread.CurrentThread, 1, 0);  
  59.          }  
  60.    
  61.          ///   
  62.          /// 通过工厂的制造模式获取相应的LINQ数据库连接对象  
  63.          ///   
  64.          ///   
  65.          ///   
  66.          ///   
  67.          ///   
  68.          public static DbContext Intance(string dbName, int dbCount, int dbIndex)  
  69.          {  
  70.              return Intance(dbName, Thread.CurrentThread, dbCount, dbIndex);  
  71.          }  
  72.    
  73.          ///   
  74.          /// 通过工厂的制造模式获取相应的LINQ数据库连接对象  
  75.          ///   
  76.          /// 数据库名称(需要与真实数据库名称保持一致)  
  77.          /// 当前线程引用的对象  
  78.          /// linq to sql数据库数量  
  79.          /// 当前索引  
  80.          /// LINQ对象上下文  
  81.          public static DbContext Intance(string dbName, Thread thread, int dbCount, int dbIndex)  
  82.          {  
  83.              if (!divDataContext.Keys.Contains(thread))  
  84.              {  
  85.                  divDataContext.Add(thread, new DbContext[dbCount]);  
  86.              }  
  87.              if (divDataContext[thread][dbIndex] == null)  
  88.              {  
  89.                  divDataContext[thread][dbIndex] = new DbContext(dbName);  
  90.              }  
  91.              return divDataContext[thread][dbIndex];  
  92.          }  
  93.    
  94.          ///   
  95.          /// 通过工厂的制造模式获取相应的LINQ数据库连接对象  
  96.          ///   
  97.          ///   
  98.          ///   
  99.          ///   
  100.          public static DbContext Intance(string dbName, Thread thread)  
  101.          {  
  102.              return Intance(dbName, thread, 1, 0);  
  103.          }  
  104.          #endregion  
  105.    
  106.      } 

具体领域数据对象创建时代码如下:

 
 
 
  1. ///   
  2.      /// XXB数据库基类  
  3.      ///   
  4.      public class XXB_DataBase : DataBase  
  5.      {  
  6.          private readonly static string _conn;  
  7.          static XXB_DataBase()  
  8.          {  
  9.              if (ConfigurationManager.ConnectionStrings["XXB"] == null)  
  10.                  throw new Exception("请设置XXB配置字符");  
  11.              else 
  12.                  _conn = ConfigurationManager.ConnectionStrings["XXB"].ToString();  
  13.          }  
  14.          public XXB_DataBase()  
  15.              : base(DbFactory.Intance(_conn, 2, 1))  
  16.          { }  
  17.    
  18.      } 

二 私有的DbContext,它要求你为每个表都建立一个repository对象,用户对表进行CURD操作,而它们都继承一个database,在 database里有唯一创建datacontext的入口,这样在做多表关联时,使用的是同一个datacontext对象,所以不会出现“不能实现不同数据上下文件的引用”这种问题,但这样方式感觉很不爽,因为你必须把所有多表关联的业务逻辑,写在DAL层,这是很郁闷的,因为一般我们会把它放在BLL层(更有利于业务的组合与重用)。

代码:

具体领域数据基类:

 
 
 
  1. ///   
  2.      /// XXB数据基类  
  3.      ///   
  4.      public abstract class XXBBase : DataBase  
  5.      {  
  6.          public XXBBase()  
  7.              : base(new LINQ.DataClasses1DataContext(System.Configuration.ConfigurationManager.ConnectionStrings["XXB"].ToString()))  
  8.          { }  
  9.      } 

统一数据基类:

 
 
 
  1. ///   
  2.      /// 标准数据操作基类  
  3.      ///   
  4.      public abstract class DataBase : IRepository  
  5.      {  
  6.          ///   
  7.          /// 数据访问对象(只对子类可见)  
  8.          ///   
  9.          protected DataContext DB;  
  10.    
  11.          #region Constructors  
  12.          public DataBase(DataContext db)  
  13.              : this(() => { return db; })  
  14.          { }  
  15.          public DataBase(Func func)  
  16.          {  
  17.              this.DB = func();  
  18.          }  
  19.          #endregion  
  20.    
  21.          #region DBContext SubmitChanges  
  22.          ///   
  23.          /// XXB默认提交【重写时候可能需要写入自定义的类似约束的逻辑】  
  24.          ///   
  25.          protected virtual void SubmitChanges()  
  26.          {  
  27.              ChangeSet cSet = DB.GetChangeSet();  
  28.              if (cSet.Inserts.Count > 0 
  29.                  || cSet.Updates.Count > 0 
  30.                  || cSet.Deletes.Count > 0)  
  31.              {  
  32.                  try 
  33.                  {  
  34.                      DB.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict);  
  35.                  }  
  36.                  catch (System.Data.Linq.ChangeConflictException)  
  37.                  {  
  38.                      foreach (System.Data.Linq.ObjectChangeConflict occ in DB.ChangeConflicts)  
  39.                      {  
  40.                          occ.Resolve(System.Data.Linq.RefreshMode.OverwriteCurrentValues);  
  41.                          occ.Resolve(System.Data.Linq.RefreshMode.KeepCurrentValues);  
  42.                          occ.Resolve(System.Data.Linq.RefreshMode.KeepChanges);  
  43.                      }  
  44.                      DB.SubmitChanges();  
  45.                  }  
  46.              }  
  47.          }  
  48.    
  49.          #endregion  
  50.    
  51.          #region IRepository 成员  
  52.    
  53.          public virtual void Update(TEntity entity) where TEntity : class 
  54.          {  
  55.              this.SubmitChanges();  
  56.    
  57.          }  
  58.    
  59.          public virtual void Update(IEnumerable list) where TEntity : class 
  60.          {  
  61.              list.ToList().ForEach(entity =>  
  62.              {  
  63.                  this.Update(entity);  
  64.              });  
  65.          }  
  66.    
  67.          public virtual void Insert(TEntity entity) where TEntity : class 
  68.          {  
  69.              DB.GetTable().InsertOnSubmit(entity);  
  70.              this.SubmitChanges();  
  71.          }  
  72.    
  73.          public virtual void Insert(IEnumerable list) where TEntity : class 
  74.          {  
  75.              DB.GetTable().InsertAllOnSubmit(list);  
  76.              this.SubmitChanges();  
  77.          }  
  78.    
  79.          public virtual TEntity InsertGetIDENTITY(TEntity entity) where TEntity : class 
  80.          {  
  81.              this.Insert(entity);  
  82.              return GetModel(i => i == entity).FirstOrDefault();  
  83.          }  
  84.    
  85.          public virtual void Delete(TEntity entity) where TEntity : class 
  86.          {  
  87.              DB.GetTable().DeleteOnSubmit(entity);  
  88.              this.SubmitChanges();  
  89.          }  
  90.    
  91.          public virtual void Delete(IEnumerable list) where TEntity : class 
  92.          {  
  93.              DB.GetTable().DeleteAllOnSubmit(list);  
  94.              this.SubmitChanges();  
  95.          }  
  96.    
  97.          public virtual IQueryable GetModel() where TEntity : class 
  98.          {  
  99.              return this.DB.GetTable();  
  100.          }  
  101.    
  102.          public virtual IQueryable GetModel(System.Linq.Expressions.Expression> predicate) where TEntity : class 
  103.          {  
  104.              return GetModel().Where(predicate);  
  105.          }  
  106.    
  107.          public virtual TEntity Find(params object[] keyValues) where TEntity : class 
  108.          {  
  109.              var mapping = DB.Mapping.GetTable(typeof(TEntity));  
  110.              var keys = mapping.RowType.IdentityMembers.Select((m, i) => m.Name + " = @" + i).ToArray();  
  111.              TEntity entityTEntity = DB.GetTable().Where(String.Join(" && ", keys), keyValues).FirstOrDefault();  
  112.              if (entityTEntity != null)  
  113.                  DB.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, entityTEntity);  
  114.              return entityTEntity;  
  115.          }  
  116.    
  117.          #endregion  
  118.      } 

而用户模块User_InfoRepository在做多表关联时,是这样完成的:

 
 
 
  1. public class User_InfoRepository : XXBBase  
  2.      {  
  3.          ///   
  4.          /// 需要把Join的表关系写在这里  
  5.          ///   
  6.          ///   
  7.          public IQueryable GetDetailModel()  
  8.          {  
  9.              var linq = from data1 in base.GetModel()  
  10.                         join data2 in base.GetModel() on data1.UserID equals data2.UserID  
  11.                         select data1;  
  12.              return linq;  
  13.          }  
  14.      } 

原文链接:http://www.cnblogs.com/lori/archive/2012/08/23/2653426.html

本文标题:线程共享的DbContext与私有的DbContext
本文链接:http://www.shufengxianlan.com/qtweb/news27/50927.html

成都网站建设公司_创新互联,为您提供建站公司网页设计公司服务器托管微信小程序网站维护自适应网站

广告

声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 创新互联