中文字幕精品亚洲无线码二区,国产黄a三级三级三级看三级,亚洲七七久久桃花影院,丰满少妇被猛烈进入,国产小视频在线观看网站

LINQ-to-SQL那點事~線程(cheng)共享的DbContext與私有(you)的DbContext

回到目錄    

  在使用Linq to Sql做為(wei)底層ORM時,它(ta)(ta)為(wei)我(wo)(wo)們(men)提供(gong)的(de)數據上(shang)下文為(wei)DataContext對(dui)象,實(shi)(shi)現上(shang)我(wo)(wo)們(men)通(tong)過(guo)拖動(dong)生(sheng)成的(de)DBML文件,它(ta)(ta)們(men)都是(shi)繼承自(zi) System.Data.Linq.DataContext類型(xing)的(de),所以(yi)DataContext就是(shi)LINQ數據對(dui)象的(de)基類,有時,我(wo)(wo)們(men)可以(yi)通(tong)過(guo)這種類的(de)多態性來動(dong)態創建DB的(de)實(shi)(shi)例(li)。

     在每個DataContext類(lei)中,它有(you)幾個實例的(de)構造方法,用來讓你創建DataContext的(de)實例,如(ru)下:

 1     /// <summary>
 2         /// 使用默認的連(lian)接串(chuan)創(chuang)建(jian)實現(xian)(每拖一(yi)次數據庫,就會產生(sheng)一(yi)個連(lian)接串(chuan))
 3         /// </summary>
 4         public DataClasses1DataContext() : 
 5                 base(global::test.Properties.Settings.Default.EEE114ConnectionString, mappingSource)
 6         {
 7             OnCreated();
 8         }
 9         /// <summary>
10         /// 使用指定的連(lian)接(jie)串,可能配置在config文(wen)件里
11         /// </summary>
12         /// <param name="connection"></param>
13         public DataClasses1DataContext(string connection) : 
14                 base(connection, mappingSource)
15         {
16             OnCreated();
17         }
18         /// <summary>
19         /// 使用使用了(le)IDbConnection接(jie)口的對象創建實例
20         /// </summary>
21         /// <param name="connection"></param>
22         public DataClasses1DataContext(System.Data.IDbConnection connection) : 
23                 base(connection, mappingSource)
24         {
25             OnCreated();
26         }
27         /// <summary>
28         /// 使用連接串(chuan)和數(shu)據庫的(de)映射文件(jian)來建立實例,mappingSource可能是一(yi)個XML文件(jian)
29         /// </summary>
30         /// <param name="connection"></param>
31         /// <param name="mappingSource"></param>
32         public DataClasses1DataContext(string connection, System.Data.Linq.Mapping.MappingSource mappingSource) : 
33                 base(connection, mappingSource)
34         {
35             OnCreated();
36         }

而我們在實現(xian)項目開發中,可(ke)能用第(di)二(er)種比(bi)較多(duo),即

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

這樣(yang),在開(kai)發(fa)環境與生(sheng)成環境只(zhi)要配置一個CONFIG文件即可(ke)。靈活。

而今天的主題是線(xian)程(cheng)共享的DbContext與(yu)私有(you)的DbContext,所(suo)以(yi)(yi)(yi)開始書歸正(zheng)轉了,對(dui)于ado.net架構(gou)中,我們往往使用一個static全局(ju)對(dui)象來完成數據訪(fang)問工作,而在(zai)linq to sql中,如果(guo)你建立一個static對(dui)象,它(ta)會(hui)出現很多問題,這(zhe)在(zai)實現開發過程(cheng)中才可以(yi)(yi)(yi)體會(hui)到,所(suo)以(yi)(yi)(yi),今天要說的不是static對(dui)象。

一(yi)(yi) 線程共享的(de)(de)(de)DbContext,說清楚一(yi)(yi)點就是(shi)(shi)(shi)在(zai)一(yi)(yi)個線程內(nei),你的(de)(de)(de)DataContext對(dui)(dui)象(xiang)是(shi)(shi)(shi)共享的(de)(de)(de),是(shi)(shi)(shi)一(yi)(yi)個對(dui)(dui)象(xiang),不是(shi)(shi)(shi)new出(chu)很多個datacontext對(dui)(dui)象(xiang)來,這事(shi)實上(shang)是(shi)(shi)(shi)一(yi)(yi)種單例(li)模式(shi)的(de)(de)(de)體現,這沒(mei)有(you)問題,它(ta)解決了static對(dui)(dui)象(xiang)所產生的(de)(de)(de)問題,而又滿足了多表關聯查詢時出(chu)現(不能實現不同數(shu)據(ju)上(shang)下文件的(de)(de)(de)引用,linq to sql和Ef都是(shi)(shi)(shi)這樣的(de)(de)(de))的(de)(de)(de)問題。

代碼:

datacontext生成工(gong)廠:

  1     /// <summary>
  2     /// 數據(ju)庫建立工廠
  3     /// Created By : 張占嶺
  4     /// Created Date:2011-10-14
  5     /// Modify By:
  6     /// Modify Date:
  7     /// Modify Reason:
  8     /// </summary>
  9     internal sealed class DbFactory
 10     {
 11         #region Fields
 12         static System.Timers.Timer sysTimer = new System.Timers.Timer(10000);
 13         volatile static Dictionary<Thread, DataContext[]> divDataContext = new Dictionary<Thread, DataContext[]>();
 14         #endregion
 15 
 16         #region Constructors
 17         /// <summary>
 18         /// 類構造(zao)方(fang)法
 19         /// </summary>
 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         /// <summary>
 32         /// 訂閱Elapsed事件(jian)的方法
 33         /// </summary>
 34         /// <param name="sender"></param>
 35         /// <param name="e"></param>
 36         static void sysTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
 37         {
 38             List<Thread> 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         /// <summary>
 52         /// 通過工廠的制造模(mo)式獲取相應(ying)的LINQ數(shu)據(ju)庫連接(jie)對象(xiang)
 53         /// </summary>
 54         /// <param name="dbName">數(shu)(shu)據(ju)庫名稱(cheng)(需要與真實數(shu)(shu)據(ju)庫名稱(cheng)保(bao)持一致)</param>
 55         /// <returns>LINQ數據庫連接對象(xiang)</returns>
 56         public static DataContextIntance(string dbName)
 57         {
 58             return Intance(dbName, Thread.CurrentThread, 1, 0);
 59         }
 60 
 61         /// <summary>
 62         /// 通過工廠的制造(zao)模式獲(huo)取相應的LINQ數據庫連接對(dui)象(xiang)
 63         /// </summary>
 64         /// <param name="dbName"></param>
 65         /// <param name="dbCount"></param>
 66         /// <param name="dbIndex"></param>
 67         /// <returns></returns>
 68         public static DataContextIntance(string dbName, int dbCount, int dbIndex)
 69         {
 70             return Intance(dbName, Thread.CurrentThread, dbCount, dbIndex);
 71         }
 72 
 73         /// <summary>
 74         /// 通過工廠的(de)制造模式獲取相應(ying)的(de)LINQ數(shu)據庫連接對象
 75         /// </summary>
 76         /// <param name="dbName">數據庫名稱(cheng)(需(xu)要(yao)與(yu)真實數據庫名稱(cheng)保(bao)持(chi)一致)</param>
 77         /// <param name="thread">當前(qian)線程引(yin)用的對象(xiang)</param>
 78         /// <param name="dbCount">linq to sql數(shu)據(ju)庫數(shu)量</param>
 79         /// <param name="dbIndex">當前索引</param>
 80         /// <returns>LINQ對象(xiang)上下文</returns>
 81         public static DataContextIntance(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         /// <summary>
 95         /// 通過工廠的(de)(de)制造模式(shi)獲取相應的(de)(de)LINQ數據庫連接對(dui)象
 96         /// </summary>
 97         /// <param name="dbName"></param>
 98         /// <param name="thread"></param>
 99         /// <returns></returns>
100         public static DataContextIntance(string dbName, Thread thread)
101         {
102             return Intance(dbName, thread, 1, 0);
103         }
104         #endregion
105 
106     }

具體(ti)領域(yu)數據(ju)對象創建(jian)時代(dai)碼如下:

 1 /// <summary>
 2     /// XXB數據庫(ku)基類
 3     /// </summary>
 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("請(qing)設置XXB配置字(zi)符");
11             else
12                 _conn = ConfigurationManager.ConnectionStrings["XXB"].ToString();
13         }
14         public XXB_DataBase()
15             : base(DbFactory.Intance(_conn, 2, 1))
16         { }
17 
18     }

 

二 私有的(de)DbContext,它要求(qiu)你(ni)(ni)為每個表都(dou)建立(li)一(yi)個repository對(dui)象,用(yong)戶(hu)對(dui)表進行(xing)CURD操作,而它們(men)都(dou)繼承一(yi)個database,在 database里有唯一(yi)創建datacontext的(de)入口,這(zhe)樣(yang)在做多表關聯時(shi),使(shi)用(yong)的(de)是(shi)同(tong)一(yi)個datacontext對(dui)象,所以不會出(chu)現(xian)“不能實現(xian)不同(tong)數據上下文件的(de)引用(yong)”這(zhe)種問題,但這(zhe)樣(yang)方式感覺很(hen)不爽,因為你(ni)(ni)必須把(ba)所有多表關聯的(de)業務邏輯,寫在DAL層,這(zhe)是(shi)很(hen)郁悶的(de),因為一(yi)般我們(men)會把(ba)它放在BLL層(更有利于業務的(de)組(zu)合(he)與重用(yong))。

代碼:

具體領域數據基類:

1  /// <summary>
2     /// XXB數據基類(lei)
3     /// </summary>
4     public abstract class XXBBase : DataBase
5     {
6         public XXBBase()
7             : base(new LINQ.DataClasses1DataContext(System.Configuration.ConfigurationManager.ConnectionStrings["XXB"].ToString()))
8         { }
9     }

統一數據基類:

  1   /// <summary>
  2     /// 標準數據(ju)操作基類
  3     /// </summary>
  4     public abstract class DataBase : IRepository
  5     {
  6         /// <summary>
  7         /// 數據訪問對(dui)象(只(zhi)對(dui)子類(lei)可見)
  8         /// </summary>
  9         protected DataContext DB;
 10 
 11         #region Constructors
 12         public DataBase(DataContext db)
 13             : this(() => { return db; })
 14         { }
 15         public DataBase(Func<DataContext> func)
 16         {
 17             this.DB = func();
 18         }
 19         #endregion
 20 
 21         #region DBContext SubmitChanges
 22         /// <summary>
 23         /// XXB默認提交【重(zhong)寫(xie)(xie)時候可能需要(yao)寫(xie)(xie)入自定義的(de)(de)類(lei)似約束(shu)的(de)(de)邏輯(ji)】
 24         /// </summary>
 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>(TEntity entity) where TEntity : class
 54         {
 55             this.SubmitChanges();
 56 
 57         }
 58 
 59         public virtual void Update<TEntity>(IEnumerable<TEntity> list) where TEntity : class
 60         {
 61             list.ToList().ForEach(entity =>
 62             {
 63                 this.Update<TEntity>(entity);
 64             });
 65         }
 66 
 67         public virtual void Insert<TEntity>(TEntity entity) where TEntity : class
 68         {
 69             DB.GetTable<TEntity>().InsertOnSubmit(entity);
 70             this.SubmitChanges();
 71         }
 72 
 73         public virtual void Insert<TEntity>(IEnumerable<TEntity> list) where TEntity : class
 74         {
 75             DB.GetTable<TEntity>().InsertAllOnSubmit<TEntity>(list);
 76             this.SubmitChanges();
 77         }
 78 
 79         public virtual TEntity InsertGetIDENTITY<TEntity>(TEntity entity) where TEntity : class
 80         {
 81             this.Insert<TEntity>(entity);
 82             return GetModel<TEntity>(i => i == entity).FirstOrDefault();
 83         }
 84 
 85         public virtual void Delete<TEntity>(TEntity entity) where TEntity : class
 86         {
 87             DB.GetTable<TEntity>().DeleteOnSubmit(entity);
 88             this.SubmitChanges();
 89         }
 90 
 91         public virtual void Delete<TEntity>(IEnumerable<TEntity> list) where TEntity : class
 92         {
 93             DB.GetTable<TEntity>().DeleteAllOnSubmit<TEntity>(list);
 94             this.SubmitChanges();
 95         }
 96 
 97         public virtual IQueryable<TEntity> GetModel<TEntity>() where TEntity : class
 98         {
 99             return this.DB.GetTable<TEntity>();
100         }
101 
102         public virtual IQueryable<TEntity> GetModel<TEntity>(System.Linq.Expressions.Expression<Func<TEntity, bool>> predicate) where TEntity : class
103         {
104             return GetModel<TEntity>().Where(predicate);
105         }
106 
107         public virtual TEntity Find<TEntity>(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<TEntity>().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     }

而用(yong)戶模塊User_InfoRepository在做多表(biao)關聯時,是(shi)這(zhe)樣完成的:

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

回到目錄

posted @ 2012-08-23 23:04  張占嶺  閱讀(3894)  評論(0)    收藏  舉報