Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介紹


無論是Linq To SQL還是Linq To Object(Entity frameworks)它們都為開發人員提供了Insert操作,及Insert集合操作,即InsertOnSubmit和InsertAllOnSubmit,前者是將一個實體標記為一個插入狀態,而后都是將一個集合標記為插入狀態,...

 

      無論是Linq To SQL還是Linq To Object(Entity frameworks)它們都為開發人員提供了Insert操作,及Insert集合操作,即InsertOnSubmit和InsertAllOnSubmit,前者是將一個實體標記為一個插入狀態,而后都是將一個集合標記為插入狀態,而當前進行這兩種操作時,你並沒有與數據庫進行連接,這就是LINQ提倡的延時加載,那它們什么時候與數據庫進行真正的交互呢,實現上,實驗表明,是在觸發SubmitChanges方法時,才會真實與數據庫進行操作,這是正常的,也沒有什么可以說的。 

     而今天我主要說的就是,當我們進行批量插入時,用linq給我們提供的InsertAllOnSubmit方法是否可以實現我們的操作,如果實現了,那是否是我們能夠接受的方式,我們在做一個實驗吧 

一個列表: 

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


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

可以肯定的說,不可以,而且是非常不可以,對於這個插入操作,它對數據服務器的壓力是驚人的,它建立“鏈接”次為10萬次,即每個Insert語句就建立一個鏈接,這是我們不能接受的,所以,LINQ的批量操作確實靠不住。 
OK,既然LINQ的方式是不可取的,那我們只好自己去動手寫了,呵呵,我們的思想去將10條Insert合並在一起,一次性發給服務器,一次性執行,對於目前的網絡帶寬這10條數據不成問題,呵呵。 

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

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

二 批量插入實體,我們采用拼接字符串,並向數據服務器發命令的方式,這個也是我比較滿足的作品,它是一個通用的方式,並且不需要修改原來插入代碼,它的 

方法簽名是一個列表,這樣做是正確的,對於程序員來說是非常友好的。 

先看之前的LINQ批量插入: 


public virtual void Insert(IEnumerable list) where TEntity : class 
       { 
           DB.GetTable().InsertAllOnSubmit(list); 
           this.SubmitChanges(); 
       } 
而在我們修改后,方法簽名是不變的,所以原來調用它的方法,不需要進行修改: 


1         /// 


2         /// ADO優化的批量添加 
3         ///


4         ///


5         ///


6         public virtual void Insert

(IEnumerable list) where TEntity : class 
7         { 
8             this.InsertForADO(list); 
9         } 
所需要的輔助方法: 


1 #region LINQ調用T-SQL實現批量添加 
2         ///
3         /// 得到數據庫表或視圖的抽象 
4         ///
5         /// 
6         /// 
7         MetaTable GetMetaTable(Type rowType) 
8         { 
9             return DB.Mapping.GetTable(rowType); 
10         } 
11 
12         ///
13         /// 建立SQL語句 
14         ///
15         /// 
16         /// 
17         Tuple<string,> CreateInsertArguments(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 arguments = new List(); 
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,>(fieldbuilder.ToString(), arguments.ToArray()); 
65         } 
66 
67         void InsertForADO(IEnumerable list) 
68         { 
69             StringBuilder sqlstr = new StringBuilder(); 
70             list.ToList().ForEach(i =>
71             { 
72                 Tuple<string,> insert = CreateInsertArguments(i); 
73                 sqlstr.AppendFormat(insert.Item1, insert.Item2); 
74             }); 
75             DB.ExecuteCommand(sqlstr.ToString()); 
76         } 
77 
78         #endregion

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM