无论是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

Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介绍的更多相关文章

  1. linq to sql and linq to object 总结

    Enumable类型是linq to object   是一个很特殊的类型   这个类型的数据源都是在程序的内存中 Queryable类型是 Linq to sql   对数据库进行操作都是这个类型  ...

  2. [LINQ TO SQL]使用LINQ TO SQL创建数据库

    这篇博客将介绍如何使用LINQ TO SQL来创建数据库,以及如何映射Table之间的主外键关系. 我们的数据库表关系如下: Province与City之间1:M,City与Area之间1:M的关系. ...

  3. 步步学LINQ to SQL:使用LINQ检索数据【转】

    [IT168 专稿]该系列教程描述了如何采用手动的方式映射你的对象类到数据表(而不是使用象SqlMetal这样的自动化工具)以便能够支持数据表之间的M:M关系和使用实体类的数据绑定.即使你选择使用了自 ...

  4. linq to sql 和linq to php 的区别

    linq to sql 这是自.net框架3.5版本以上做出了相关规定. linq to php .Net的linq库的忠实移植到PHP 这个库使得大量使用匿名函数在PHP 5.3中引入的功能.因此, ...

  5. Difference between LINQ to SQL and LINQ to Entity(DataContext and DbContext)

    http://msdn.microsoft.com/en-us/library/cc161164.aspx http://stackoverflow.com/questions/2443836/wha ...

  6. LINQ / LINQ to SQL / LINQ to XXX 它们到底有什么区别

    LINQ是新生事物,不过从不少文章和讨论上看来,这方面的概念也已经有点混沌不清了.因此我们经常可以看到这样的话: LINQ只能将数据表与实体属性一一对应…… LINQ开发指南:在LINQ中进行数据库字 ...

  7. MVC 学习(二)之Linq to Sql 简单Demo

    Linq to Entities 已经我的一篇博文中阐述了,这里阐述一下简单的Linq to Sql 的增删改查.Linq to sql 与Linq to Entities虽然同属于DataBase- ...

  8. linq世界走一走(LINQ TO SQL)

    前言:作为linq的一个组件,同时作为ADO.NET的一个组成部分,LINQ TO SQL提供了将关系数据映射为对象的运行时基础结构. LINQ TO SQL是通过将关系数据库对象的数据模型(如一个数 ...

  9. LINQ to SQL大全

    LINQ to SQL语句 (1)之Where Where操作 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的 ...

随机推荐

  1. HDU3480 Division——四边形不等式或斜率优化

    题目大意 将N个数分成M部分,使每部分的最大值与最小值平方差的和最小. 思路 首先肯定要将数列排序,每部分一定是取连续的一段,于是就有了方程 $\Large f(i,j)=min(f(i-1,k-1) ...

  2. 【笔记篇】C#笔记1

    返回目录:目录请戳这里~ 以后的C#笔记如果不出意外的话都是Win10 Professional + VS2015 Professional出的,(当然还有直接在编译框敲的所以能不能过编译我也不知道┑ ...

  3. python spark环境配置

              在配置Hadoop之前,应该先做以下配置   1.更改主机名 首先更改主机名,目的是为了方便管理.  输入:hostname  查看本机的名称  使用 hostname 修改当前主 ...

  4. activeMQ消息队列安装配置

    1.  下载 到官网下载最新版本,有windows版本和linux版本的. http://activemq.apache.org/download.html 2.   windows下部署 Activ ...

  5. python Mean Squared Error vs. Structural Similarity Measure两种算法的图片比较

    # by movie on 2019/12/18 import matplotlib.pyplot as plt import numpy as np from skimage import meas ...

  6. Oracle使用语句块之循环插入数据

    1.业务要求:  将oracle表A的整表的数据一次性导入到表B中 , 以A_ID为外键关联. (*******如果开发环境和实际生产环境的数据一致,而且数据量比较小情况,可以直接手动添加数据; ** ...

  7. Workman-Thrift疑问解析

    Workman是纯纯的PHP实现的一套网络通信框架,Workman-Thrift则是以Workman为基础,为Thrift RPC实现网络通信.经过学习与测试,现把自己的疑问与验证记录下来: 问题一: ...

  8. VS2010编译的时候出现fatal error LNK1146: 没有用选项“/out:”指定的参数

    最近安装了下vs2010,发现对硬件要求还是很高的,先是在一个一般台式机上安装出现字体发虚的问题,操作系统也是vista sp2,尝试了网上若干方法还是发虚,总结就是硬件的显卡不行,3年前的机器了:遂 ...

  9. [TJOI2017]城市 【树的直径+暴力+优化】

    Online Judge:Luogu P3761 Label:树的直径,暴力 题目描述 从加里敦大学城市规划专业毕业的小明来到了一个地区城市规划局工作.这个地区一共有n座城市,n-1条高速公路,保证了 ...

  10. React学习整理

    React介绍 React设计思想及其独特,属于革命性创新,性能出众,代码逻辑却非常简单. 库(library):小而巧,库只提供了特定的api.优点是船小好调头,可以很方便的从一个库切换到另外的库, ...