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

將不(bu)確(que)定(ding)變為確(que)定(ding)系列~Linq的批(pi)量(liang)操作靠的住(zhu)嗎?

回到目錄     

無論(lun)是(shi)Linq To SQL還是(shi)Linq To Object(Entity frameworks)它們(men)都為(wei)開(kai)發(fa)人員提供了(le)Insert操(cao)作,及Insert集合操(cao)作,即InsertOnSubmit和InsertAllOnSubmit,前者是(shi)將一個實體(ti)標記(ji)為(wei)一個插入狀態(tai)(tai),而后都是(shi)將一個集合標記(ji)為(wei)插入狀態(tai)(tai),而當前進(jin)(jin)行(xing)(xing)這(zhe)兩(liang)種操(cao)作時(shi),你并沒有與(yu)(yu)數據(ju)庫(ku)進(jin)(jin)行(xing)(xing)連接,這(zhe)就是(shi)LINQ提倡的(de)(de)(de)延(yan)時(shi)加載,那它們(men)什(shen)么(me)時(shi)候(hou)與(yu)(yu)數據(ju)庫(ku)進(jin)(jin)行(xing)(xing)真(zhen)正的(de)(de)(de)交互呢(ni),實現上,實驗表明,是(shi)在觸發(fa)SubmitChanges方法時(shi),才會真(zhen)實與(yu)(yu)數據(ju)庫(ku)進(jin)(jin)行(xing)(xing)操(cao)作,這(zhe)是(shi)正常的(de)(de)(de),也(ye)沒有什(shen)么(me)可以(yi)說的(de)(de)(de)。

      而今(jin)天(tian)我(wo)(wo)主(zhu)要說的(de)就是(shi),當我(wo)(wo)們(men)進行(xing)批量(liang)插(cha)入時,用linq給我(wo)(wo)們(men)提供的(de)InsertAllOnSubmit方法是(shi)否可以實(shi)(shi)現我(wo)(wo)們(men)的(de)操(cao)作,如果(guo)實(shi)(shi)現了,那是(shi)否是(shi)我(wo)(wo)們(men)能夠接受(shou)的(de)方式,我(wo)(wo)們(men)在(zai)做一個(ge)實(shi)(shi)驗吧

一個列表:

1 List<User> userList=new List<User>();
2 
3 for(int i=0;i<100000;i++)
4 {
5   userList.Add(new User{Name="zzl"+i});
6 }
7 _db.InsertAllOnSubmit(userList);
8 
9 _db.SubmitChanges();


結果怎么樣呢?經過我的(de)觀察,結果是(shi)正確的(de),10萬條數據可以插入(ru)到數據庫中,LINQ確實是(shi)幫助我們完成了列表的(de)插入(ru)工作,但(dan)過程我們是(shi)否可以接受?

可以肯定的說,不可以,而且是非常不可以,對于這個插入操作,它對數據服務器的壓力是驚人的,它建立“鏈接”次為10萬次,即每個Insert語句就建立一個鏈接,這是我們不能接受的,所以,LINQ的批量操作確實靠不住。

OK,既(ji)然LINQ的方式是不(bu)可取(qu)的,那我們只好自(zi)己去動手寫(xie)了,呵呵,我們的思想(xiang)去將(jiang)10條Insert合并在一起,一次性發給服務器,一次性執行,對于目前(qian)的網絡帶(dai)寬這(zhe)10條數據不(bu)成(cheng)問題,呵呵。

一 單個實體的(de)Insert,我們采用LINQ的(de)延時(shi)插入方(fang)式:

1  public virtual void Insert<TEntity>(TEntity entity) where TEntity : class
2         {
3             DB.GetTable<TEntity>().InsertOnSubmit(entity);
4             this.SubmitChanges();
5         }

二 批量插入實體,我(wo)們采用拼接字符串,并向數(shu)據服務(wu)器發命令的方式,這(zhe)個也是我(wo)比(bi)較(jiao)滿(man)足的作品,它(ta)是一(yi)個通用的方式,并且不需(xu)要(yao)修(xiu)改原來插入代(dai)碼,它(ta)的

方法(fa)簽名是(shi)(shi)一個列(lie)表(biao),這樣做是(shi)(shi)正(zheng)確的(de),對于程序員來說是(shi)(shi)非常友(you)好(hao)的(de)。

先看之前(qian)的LINQ批量(liang)插入:

 public virtual void Insert<TEntity>(IEnumerable<TEntity> list) where TEntity : class
        {
            DB.GetTable<TEntity>().InsertAllOnSubmit(list);
            this.SubmitChanges();
        }

而(er)在我們(men)修改后(hou),方(fang)法簽名(ming)是(shi)不(bu)變的,所以(yi)原來調(diao)用它(ta)的方(fang)法,不(bu)需(xu)要進行(xing)修改:

1         /// <summary>
2         /// ADO優化的批量添加
3         /// </summary>
4         /// <typeparam name="TEntity">&lt;/typeparam>
5         /// <param name="list"></param>
6         public virtual void Insert<TEntity>(IEnumerable<TEntity> list) where TEntity : class
7         {
8             this.InsertForADO<TEntity>(list);
9         }

所需要的輔助方法:

 1 #region LINQ調用T-SQL實現批量添加
 2         /// <summary>
 3         /// 得到數據庫表或視圖的抽象
 4         /// </summary>
 5         /// <param name="rowType"></param>
 6         /// <returns></returns>
 7         MetaTable GetMetaTable(Type rowType)
 8         {
 9             return DB.Mapping.GetTable(rowType);
10         }
11 
12         /// <summary>
13         /// 建(jian)立(li)SQL語句
14         /// </summary>
15         /// <param name="entity"></param>
16         /// <returns></returns>
17         Tuple<string, object[]> CreateInsertArguments<TEntity>(TEntity entity)
18         {
19             if (entity == null)
20                 throw new ArgumentException("The database entity can not be null.");
21 
22             Type entityType = entity.GetType();
23             MetaTable table = GetMetaTable(entityType);
24             MetaDataMember identityDatamember = table.RowType.DBGeneratedIdentityMember;
25 
26             List<object> arguments = new List<object>();
27             StringBuilder fieldbuilder = new StringBuilder();
28             StringBuilder valuebuilder = new StringBuilder();
29 
30             fieldbuilder.Append("INSERT INTO " + table.TableName + " (");
31 
32             foreach (var member in table.RowType.PersistentDataMembers)
33             {
34 
35                 if (!member.IsAssociation && !member.IsDbGenerated)
36                 {
37                     object value = entityType.GetProperty(member.Name).GetValue(entity, null);
38                     if (value != null)
39                     {
40                         if (arguments.Count != 0)
41                         {
42                             fieldbuilder.Append(", ");
43                             valuebuilder.Append(", ");
44                         }
45 
46                         fieldbuilder.Append(member.MappedName);
47                         if (member.Type == typeof(string) || member.Type == typeof(DateTime))
48                             valuebuilder.Append("'{" + arguments.Count + "}'");
49                         else
50                             valuebuilder.Append("{" + arguments.Count + "}");
51                         if (value.GetType() == typeof(string))
52                             value = value.ToString().Replace("'", "char(39)");
53                         arguments.Add(value);
54 
55                     }
56                 }
57             }
58 
59 
60             fieldbuilder.Append(") Values (");
61 
62             fieldbuilder.Append(valuebuilder.ToString());
63             fieldbuilder.Append(");");
64             return new Tuple<string, object[]>(fieldbuilder.ToString(), arguments.ToArray());
65         }
66 
67         void InsertForADO<TEntity>(IEnumerable<TEntity> list)
68         {
69             StringBuilder sqlstr = new StringBuilder();
70             list.ToList().ForEach(i =>
71             {
72                 Tuple<string, object[]> insert = CreateInsertArguments(i);
73                 sqlstr.AppendFormat(insert.Item1, insert.Item2);
74             });
75             DB.ExecuteCommand(sqlstr.ToString());
76         }
77 
78         #endregion

接下來(lai)的時間,我將會繼續寫(xie)一個批量更(geng)新和批量刪除,敬請收(shou)看(kan),呵(he)呵(he)。

回到目錄

posted @ 2012-09-22 23:18  張占嶺  閱讀(1303)  評論(2)    收藏  舉報