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

创新互联致力于互联网网站建设与网站营销,提供成都网站制作、网站设计、外贸网站建设、网站开发、seo优化、网站排名、互联网营销、成都微信小程序、公众号商城、等建站开发,创新互联网站建设策划专家,为不同类型的客户提供良好的互联网应用定制解决方案,帮助客户在新的全球化互联网环境中保持优势。
在每个DataContext类中,它有几个实例的构造方法,用来让你创建DataContext的实例,如下:
- ///
 - /// 使用默认的连接串创建实现(每拖一次数据库,就会产生一个连接串)
 - ///
 - public DataClasses1DataContext() :
 - base(global::test.Properties.Settings.Default.EEE114ConnectionString, mappingSource)
 - {
 - OnCreated();
 - }
 - ///
 - /// 使用指定的连接串,可能配置在config文件里
 - ///
 - ///
 - public DataClasses1DataContext(string connection) :
 - base(connection, mappingSource)
 - {
 - OnCreated();
 - }
 - ///
 - /// 使用使用了IDbConnection接口的对象创建实例
 - ///
 - ///
 - public DataClasses1DataContext(System.Data.IDbConnection connection) :
 - base(connection, mappingSource)
 - {
 - OnCreated();
 - }
 - ///
 - /// 使用连接串和数据库的映射文件来建立实例,mappingSource可能是一个XML文件
 - ///
 - ///
 - ///
 - public DataClasses1DataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
 - base(connection, mappingSource)
 - {
 - OnCreated();
 - }
 
而我们在实现项目开发中,可能用第二种比较多,即
- 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生成工厂:
- ///
 - /// 数据库建立工厂
 - /// Created By : 张占岭
 - /// Created Date:2011-10-14
 - /// Modify By:
 - /// Modify Date:
 - /// Modify Reason:
 - ///
 - internal sealed class DbFactory
 - {
 - #region Fields
 - static System.Timers.Timer sysTimer = new System.Timers.Timer(10000);
 - volatile static Dictionary
 divDataContext = new Dictionary (); - #endregion
 - #region Constructors
 - ///
 - /// 类构造方法
 - ///
 - static DbFactory()
 - {
 - sysTimer.AutoReset = true;
 - sysTimer.Enabled = true;
 - sysTimer.Elapsed += new System.Timers.ElapsedEventHandler(sysTimer_Elapsed);
 - sysTimer.Start();
 - }
 - #endregion
 - #region Static Methods
 - ///
 - /// 订阅Elapsed事件的方法
 - ///
 - ///
 - ///
 - static void sysTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
 - {
 - List
 list = divDataContext.Keys.Where(item => item.ThreadState == ThreadState.Stopped).ToList(); - for (int index = 0; index < list.Count; index++)
 - {
 - for (int refer = 0; refer < divDataContext[list[index]].Length; refer++)
 - if (divDataContext[list[index]][refer] != null)
 - {
 - divDataContext[list[index]][refer].Dispose();
 - divDataContext[list[index]][refer] = null;
 - }
 - divDataContext.Remove(list[index]);
 - list[index] = null;
 - }
 - }
 - ///
 - /// 通过工厂的制造模式获取相应的LINQ数据库连接对象
 - ///
 - /// 数据库名称(需要与真实数据库名称保持一致)
 - ///
 LINQ数据库连接对象 - public static DbContext Intance(string dbName)
 - {
 - return Intance(dbName, Thread.CurrentThread, 1, 0);
 - }
 - ///
 - /// 通过工厂的制造模式获取相应的LINQ数据库连接对象
 - ///
 - ///
 - ///
 - ///
 - ///
 - public static DbContext Intance(string dbName, int dbCount, int dbIndex)
 - {
 - return Intance(dbName, Thread.CurrentThread, dbCount, dbIndex);
 - }
 - ///
 - /// 通过工厂的制造模式获取相应的LINQ数据库连接对象
 - ///
 - /// 数据库名称(需要与真实数据库名称保持一致)
 - /// 当前线程引用的对象
 - /// linq to sql数据库数量
 - /// 当前索引
 - ///
 LINQ对象上下文 - public static DbContext Intance(string dbName, Thread thread, int dbCount, int dbIndex)
 - {
 - if (!divDataContext.Keys.Contains(thread))
 - {
 - divDataContext.Add(thread, new DbContext[dbCount]);
 - }
 - if (divDataContext[thread][dbIndex] == null)
 - {
 - divDataContext[thread][dbIndex] = new DbContext(dbName);
 - }
 - return divDataContext[thread][dbIndex];
 - }
 - ///
 - /// 通过工厂的制造模式获取相应的LINQ数据库连接对象
 - ///
 - ///
 - ///
 - ///
 - public static DbContext Intance(string dbName, Thread thread)
 - {
 - return Intance(dbName, thread, 1, 0);
 - }
 - #endregion
 - }
 
具体领域数据对象创建时代码如下:
- ///
 - /// XXB数据库基类
 - ///
 - public class XXB_DataBase : DataBase
 - {
 - private readonly static string _conn;
 - static XXB_DataBase()
 - {
 - if (ConfigurationManager.ConnectionStrings["XXB"] == null)
 - throw new Exception("请设置XXB配置字符");
 - else
 - _conn = ConfigurationManager.ConnectionStrings["XXB"].ToString();
 - }
 - public XXB_DataBase()
 - : base(DbFactory.Intance(_conn, 2, 1))
 - { }
 - }
 
二 私有的DbContext,它要求你为每个表都建立一个repository对象,用户对表进行CURD操作,而它们都继承一个database,在 database里有唯一创建datacontext的入口,这样在做多表关联时,使用的是同一个datacontext对象,所以不会出现“不能实现不同数据上下文件的引用”这种问题,但这样方式感觉很不爽,因为你必须把所有多表关联的业务逻辑,写在DAL层,这是很郁闷的,因为一般我们会把它放在BLL层(更有利于业务的组合与重用)。
代码:
具体领域数据基类:
- ///
 - /// XXB数据基类
 - ///
 - public abstract class XXBBase : DataBase
 - {
 - public XXBBase()
 - : base(new LINQ.DataClasses1DataContext(System.Configuration.ConfigurationManager.ConnectionStrings["XXB"].ToString()))
 - { }
 - }
 
统一数据基类:
- ///
 - /// 标准数据操作基类
 - ///
 - public abstract class DataBase : IRepository
 - {
 - ///
 - /// 数据访问对象(只对子类可见)
 - ///
 - protected DataContext DB;
 - #region Constructors
 - public DataBase(DataContext db)
 - : this(() => { return db; })
 - { }
 - public DataBase(Func
 func) - {
 - this.DB = func();
 - }
 - #endregion
 - #region DBContext SubmitChanges
 - ///
 - /// XXB默认提交【重写时候可能需要写入自定义的类似约束的逻辑】
 - ///
 - protected virtual void SubmitChanges()
 - {
 - ChangeSet cSet = DB.GetChangeSet();
 - if (cSet.Inserts.Count > 0
 - || cSet.Updates.Count > 0
 - || cSet.Deletes.Count > 0)
 - {
 - try
 - {
 - DB.SubmitChanges(System.Data.Linq.ConflictMode.ContinueOnConflict);
 - }
 - catch (System.Data.Linq.ChangeConflictException)
 - {
 - foreach (System.Data.Linq.ObjectChangeConflict occ in DB.ChangeConflicts)
 - {
 - occ.Resolve(System.Data.Linq.RefreshMode.OverwriteCurrentValues);
 - occ.Resolve(System.Data.Linq.RefreshMode.KeepCurrentValues);
 - occ.Resolve(System.Data.Linq.RefreshMode.KeepChanges);
 - }
 - DB.SubmitChanges();
 - }
 - }
 - }
 - #endregion
 - #region IRepository 成员
 - public virtual void Update
 (TEntity entity) where TEntity : class - {
 - this.SubmitChanges();
 - }
 - public virtual void Update
 (IEnumerable list) where TEntity : class - {
 - list.ToList().ForEach(entity =>
 - {
 - this.Update
 (entity); - });
 - }
 - public virtual void Insert
 (TEntity entity) where TEntity : class - {
 - DB.GetTable
 ().InsertOnSubmit(entity); - this.SubmitChanges();
 - }
 - public virtual void Insert
 (IEnumerable list) where TEntity : class - {
 - DB.GetTable
 ().InsertAllOnSubmit (list); - this.SubmitChanges();
 - }
 - public virtual TEntity InsertGetIDENTITY
 (TEntity entity) where TEntity : class - {
 - this.Insert
 (entity); - return GetModel
 (i => i == entity).FirstOrDefault(); - }
 - public virtual void Delete
 (TEntity entity) where TEntity : class - {
 - DB.GetTable
 ().DeleteOnSubmit(entity); - this.SubmitChanges();
 - }
 - public virtual void Delete
 (IEnumerable list) where TEntity : class - {
 - DB.GetTable
 ().DeleteAllOnSubmit (list); - this.SubmitChanges();
 - }
 - public virtual IQueryable
 GetModel () where TEntity : class - {
 - return this.DB.GetTable
 (); - }
 - public virtual IQueryable
 GetModel (System.Linq.Expressions.Expression > predicate) where TEntity : class - {
 - return GetModel
 ().Where(predicate); - }
 - public virtual TEntity Find
 (params object[] keyValues) where TEntity : class - {
 - var mapping = DB.Mapping.GetTable(typeof(TEntity));
 - var keys = mapping.RowType.IdentityMembers.Select((m, i) => m.Name + " = @" + i).ToArray();
 - TEntity entityTEntity = DB.GetTable
 ().Where(String.Join(" && ", keys), keyValues).FirstOrDefault(); - if (entityTEntity != null)
 - DB.Refresh(System.Data.Linq.RefreshMode.OverwriteCurrentValues, entityTEntity);
 - return entityTEntity;
 - }
 - #endregion
 - }
 
而用户模块User_InfoRepository在做多表关联时,是这样完成的:
- public class User_InfoRepository : XXBBase
 - {
 - ///
 - /// 需要把Join的表关系写在这里
 - ///
 - ///
 - public IQueryable
 GetDetailModel() - {
 - var linq = from data1 in base.GetModel
 () - join data2 in base.GetModel
 () on data1.UserID equals data2.UserID - select data1;
 - return linq;
 - }
 - }
 
原文链接:http://www.cnblogs.com/lori/archive/2012/08/23/2653426.html
                本文标题:线程共享的DbContext与私有的DbContext
                
                浏览路径:http://www.csdahua.cn/qtweb/news27/50927.html
            
网站建设、网络推广公司-快上网,是专注品牌与效果的网站制作,网络营销seo公司;服务项目有等
声明:本网站发布的内容(图片、视频和文字)以用户投稿、用户转载内容为主,如果涉及侵权请尽快告知,我们将会在第一时间删除。文章观点不代表本网站立场,如需处理请联系客服。电话:028-86922220;邮箱:631063699@qq.com。内容未经允许不得转载,或转载时需注明来源: 快上网