新聞中心
在使用Linq to Sql做為底層ORM時(shí),它為我們提供的數(shù)據(jù)上下文為DataContext對(duì)象,實(shí)現(xiàn)上我們通過(guò)拖動(dòng)生成的DBML文件,它們都是繼承自 System.Data.Linq.DataContext類型的,所以DataContext就是LINQ數(shù)據(jù)對(duì)象的基類,有時(shí),我們可以通過(guò)這種類的多態(tài)性來(lái)動(dòng)態(tài)創(chuàng)建DB的實(shí)例。

創(chuàng)新互聯(lián)致力于互聯(lián)網(wǎng)網(wǎng)站建設(shè)與網(wǎng)站營(yíng)銷,提供成都網(wǎng)站制作、網(wǎng)站設(shè)計(jì)、外貿(mào)網(wǎng)站建設(shè)、網(wǎng)站開發(fā)、seo優(yōu)化、網(wǎng)站排名、互聯(lián)網(wǎng)營(yíng)銷、成都微信小程序、公眾號(hào)商城、等建站開發(fā),創(chuàng)新互聯(lián)網(wǎng)站建設(shè)策劃專家,為不同類型的客戶提供良好的互聯(lián)網(wǎng)應(yīng)用定制解決方案,幫助客戶在新的全球化互聯(lián)網(wǎng)環(huán)境中保持優(yōu)勢(shì)。
在每個(gè)DataContext類中,它有幾個(gè)實(shí)例的構(gòu)造方法,用來(lái)讓你創(chuàng)建DataContext的實(shí)例,如下:
- ///
- /// 使用默認(rèn)的連接串創(chuàng)建實(shí)現(xiàn)(每拖一次數(shù)據(jù)庫(kù),就會(huì)產(chǎn)生一個(gè)連接串)
- ///
- public DataClasses1DataContext() :
- base(global::test.Properties.Settings.Default.EEE114ConnectionString, mappingSource)
- {
- OnCreated();
- }
- ///
- /// 使用指定的連接串,可能配置在config文件里
- ///
- ///
- public DataClasses1DataContext(string connection) :
- base(connection, mappingSource)
- {
- OnCreated();
- }
- ///
- /// 使用使用了IDbConnection接口的對(duì)象創(chuàng)建實(shí)例
- ///
- ///
- public DataClasses1DataContext(System.Data.IDbConnection connection) :
- base(connection, mappingSource)
- {
- OnCreated();
- }
- ///
- /// 使用連接串和數(shù)據(jù)庫(kù)的映射文件來(lái)建立實(shí)例,mappingSource可能是一個(gè)XML文件
- ///
- ///
- ///
- public DataClasses1DataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) :
- base(connection, mappingSource)
- {
- OnCreated();
- }
而我們?cè)趯?shí)現(xiàn)項(xiàng)目開發(fā)中,可能用第二種比較多,即
- DataClasses1DataContext db=new LINQ.DataClasses1DataContext(System.Configuration.ConfigurationManager.ConnectionStrings["XXB"].ToString())
這樣,在開發(fā)環(huán)境與生成環(huán)境只要配置一個(gè)CONFIG文件即可。靈活。
而今天的主題是線程共享的DbContext與私有的DbContext,所以開始書歸正轉(zhuǎn)了,對(duì)于ado.net架構(gòu)中,我們往往使用一個(gè)static全局對(duì)象來(lái)完成數(shù)據(jù)訪問(wèn)工作,而在linq to sql中,如果你建立一個(gè)static對(duì)象,它會(huì)出現(xiàn)很多問(wèn)題,這在實(shí)現(xiàn)開發(fā)過(guò)程中才可以體會(huì)到,所以,今天要說(shuō)的不是static對(duì)象。
一 線程共享的DbContext,說(shuō)清楚一點(diǎn)就是在一個(gè)線程內(nèi),你的DataContext對(duì)象是共享的,是一個(gè)對(duì)象,不是new出很多個(gè)datacontext對(duì)象來(lái),這事實(shí)上是一種單例模式的體現(xiàn),這沒有問(wèn)題,它解決了static對(duì)象所產(chǎn)生的問(wèn)題,而又滿足了多表關(guān)聯(lián)查詢時(shí)出現(xiàn)(不能實(shí)現(xiàn)不同數(shù)據(jù)上下文件的引用,linq to sql和Ef都是這樣的)的問(wèn)題。
代碼:
datacontext生成工廠:
- ///
- /// 數(shù)據(jù)庫(kù)建立工廠
- /// 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
- ///
- /// 類構(gòu)造方法
- ///
- 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;
- }
- }
- ///
- /// 通過(guò)工廠的制造模式獲取相應(yīng)的LINQ數(shù)據(jù)庫(kù)連接對(duì)象
- ///
- /// 數(shù)據(jù)庫(kù)名稱(需要與真實(shí)數(shù)據(jù)庫(kù)名稱保持一致)
- ///
LINQ數(shù)據(jù)庫(kù)連接對(duì)象 - public static DbContext Intance(string dbName)
- {
- return Intance(dbName, Thread.CurrentThread, 1, 0);
- }
- ///
- /// 通過(guò)工廠的制造模式獲取相應(yīng)的LINQ數(shù)據(jù)庫(kù)連接對(duì)象
- ///
- ///
- ///
- ///
- ///
- public static DbContext Intance(string dbName, int dbCount, int dbIndex)
- {
- return Intance(dbName, Thread.CurrentThread, dbCount, dbIndex);
- }
- ///
- /// 通過(guò)工廠的制造模式獲取相應(yīng)的LINQ數(shù)據(jù)庫(kù)連接對(duì)象
- ///
- /// 數(shù)據(jù)庫(kù)名稱(需要與真實(shí)數(shù)據(jù)庫(kù)名稱保持一致)
- /// 當(dāng)前線程引用的對(duì)象
- /// linq to sql數(shù)據(jù)庫(kù)數(shù)量
- /// 當(dāng)前索引
- ///
LINQ對(duì)象上下文 - 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];
- }
- ///
- /// 通過(guò)工廠的制造模式獲取相應(yīng)的LINQ數(shù)據(jù)庫(kù)連接對(duì)象
- ///
- ///
- ///
- ///
- public static DbContext Intance(string dbName, Thread thread)
- {
- return Intance(dbName, thread, 1, 0);
- }
- #endregion
- }
具體領(lǐng)域數(shù)據(jù)對(duì)象創(chuàng)建時(shí)代碼如下:
- ///
- /// XXB數(shù)據(jù)庫(kù)基類
- ///
- public class XXB_DataBase : DataBase
- {
- private readonly static string _conn;
- static XXB_DataBase()
- {
- if (ConfigurationManager.ConnectionStrings["XXB"] == null)
- throw new Exception("請(qǐng)?jiān)O(shè)置XXB配置字符");
- else
- _conn = ConfigurationManager.ConnectionStrings["XXB"].ToString();
- }
- public XXB_DataBase()
- : base(DbFactory.Intance(_conn, 2, 1))
- { }
- }
二 私有的DbContext,它要求你為每個(gè)表都建立一個(gè)repository對(duì)象,用戶對(duì)表進(jìn)行CURD操作,而它們都繼承一個(gè)database,在 database里有唯一創(chuàng)建datacontext的入口,這樣在做多表關(guān)聯(lián)時(shí),使用的是同一個(gè)datacontext對(duì)象,所以不會(huì)出現(xiàn)“不能實(shí)現(xiàn)不同數(shù)據(jù)上下文件的引用”這種問(wèn)題,但這樣方式感覺很不爽,因?yàn)槟惚仨毎阉卸啾黻P(guān)聯(lián)的業(yè)務(wù)邏輯,寫在DAL層,這是很郁悶的,因?yàn)橐话阄覀儠?huì)把它放在BLL層(更有利于業(yè)務(wù)的組合與重用)。
代碼:
具體領(lǐng)域數(shù)據(jù)基類:
- ///
- /// XXB數(shù)據(jù)基類
- ///
- public abstract class XXBBase : DataBase
- {
- public XXBBase()
- : base(new LINQ.DataClasses1DataContext(System.Configuration.ConfigurationManager.ConnectionStrings["XXB"].ToString()))
- { }
- }
統(tǒng)一數(shù)據(jù)基類:
- ///
- /// 標(biāo)準(zhǔn)數(shù)據(jù)操作基類
- ///
- public abstract class DataBase : IRepository
- {
- ///
- /// 數(shù)據(jù)訪問(wèn)對(duì)象(只對(duì)子類可見)
- ///
- protected DataContext DB;
- #region Constructors
- public DataBase(DataContext db)
- : this(() => { return db; })
- { }
- public DataBase(Func
func) - {
- this.DB = func();
- }
- #endregion
- #region DBContext SubmitChanges
- ///
- /// XXB默認(rèn)提交【重寫時(shí)候可能需要寫入自定義的類似約束的邏輯】
- ///
- 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在做多表關(guān)聯(lián)時(shí),是這樣完成的:
- public class User_InfoRepository : XXBBase
- {
- ///
- /// 需要把Join的表關(guān)系寫在這里
- ///
- ///
- 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
網(wǎng)站題目:線程共享的DbContext與私有的DbContext
文章轉(zhuǎn)載:http://m.5511xx.com/article/cogocoh.html


咨詢
建站咨詢
