?????? 无论是Linq To SQL还是Linq To Object(Entity frameworks)它们都为开发人员提供了Insert操作,及Insert集合操作,即InsertOnSubmit和InsertAllOnSubmit,前者是将一个实体标记为一个插入状态,而后都是将一个集合标记为插入状态,而当前进行这两种操作时,你并没有与数据库进行连接,这就是LINQ提倡的延时加载,那它们什么时候与数据库进行真正的交互呢,实现上,实验表明,是在触发SubmitChanges方法时,才会真实与数据库进行操作,这是正常的,也没有什么可以说的。 
????? 而今天我主要说的就是,当我们进行批量插入时,用linq给我们提供的InsertAllOnSubmit方法是否可以实现我们的操作,如果实现了,那是否是我们能够接受的方式,我们在做一个实验吧 
一个列表: 
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(); 
结果怎么样呢?经过我的观察,结果是正确的,10万条数据可以插入到数据库中,LINQ确实是帮助我们完成了列表的插入工作,但过程我们是否可以接受? 
可以肯定的说,不可以,而且是非常不可以,对于这个插入操作,它对数据服务器的压力是惊人的,它建立“链接”次为10万次,即每个Insert语句就建立一个链接,这是我们不能接受的,所以,LINQ的批量操作确实靠不住。 
OK,既然LINQ的方式是不可取的,那我们只好自己去动手写了,呵呵,我们的思想去将10条Insert合并在一起,一次性发给服务器,一次性执行,对于目前的网络带宽这10条数据不成问题,呵呵。 
一 单个实体的Insert,我们采用LINQ的延时插入方式: 
1? public virtual void Insert<TEntity>(TEntity entity) where TEntity : class 
2???????? { 
3???????????? DB.GetTable<TEntity>().InsertOnSubmit(entity); 
4???????????? this.SubmitChanges(); 
5???????? } 
二 批量插入实体,我们采用拼接字符串,并向数据服务器发命令的方式,这个也是我比较满足的作品,它是一个通用的方式,并且不需要修改原来插入代码,它的 
方法签名是一个列表,这样做是正确的,对于程序员来说是非常友好的。 
先看之前的LINQ批量插入: 
public virtual void Insert<TEntity>(IEnumerable<TEntity> list) where TEntity : class 
??????? { 
??????????? DB.GetTable<TEntity>().InsertAllOnSubmit(list); 
??????????? this.SubmitChanges(); 
??????? } 
而在我们修改后,方法签名是不变的,所以原来调用它的方法,不需要进行修改: 
1???????? /// <summary> 
2???????? /// ADO优化的批量添加 
3???????? /// </summary> 
4???????? /// <typeparam name="TEntity"></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???????? /// 建立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
?
?
?
