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
Linq To SQL和Linq To Object的批量操作InsertAllOnSubmit介绍的更多相关文章
- linq to sql and linq to object 总结
Enumable类型是linq to object 是一个很特殊的类型 这个类型的数据源都是在程序的内存中 Queryable类型是 Linq to sql 对数据库进行操作都是这个类型 ...
- [LINQ TO SQL]使用LINQ TO SQL创建数据库
这篇博客将介绍如何使用LINQ TO SQL来创建数据库,以及如何映射Table之间的主外键关系. 我们的数据库表关系如下: Province与City之间1:M,City与Area之间1:M的关系. ...
- 步步学LINQ to SQL:使用LINQ检索数据【转】
[IT168 专稿]该系列教程描述了如何采用手动的方式映射你的对象类到数据表(而不是使用象SqlMetal这样的自动化工具)以便能够支持数据表之间的M:M关系和使用实体类的数据绑定.即使你选择使用了自 ...
- linq to sql 和linq to php 的区别
linq to sql 这是自.net框架3.5版本以上做出了相关规定. linq to php .Net的linq库的忠实移植到PHP 这个库使得大量使用匿名函数在PHP 5.3中引入的功能.因此, ...
- 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 ...
- LINQ / LINQ to SQL / LINQ to XXX 它们到底有什么区别
LINQ是新生事物,不过从不少文章和讨论上看来,这方面的概念也已经有点混沌不清了.因此我们经常可以看到这样的话: LINQ只能将数据表与实体属性一一对应…… LINQ开发指南:在LINQ中进行数据库字 ...
- MVC 学习(二)之Linq to Sql 简单Demo
Linq to Entities 已经我的一篇博文中阐述了,这里阐述一下简单的Linq to Sql 的增删改查.Linq to sql 与Linq to Entities虽然同属于DataBase- ...
- linq世界走一走(LINQ TO SQL)
前言:作为linq的一个组件,同时作为ADO.NET的一个组成部分,LINQ TO SQL提供了将关系数据映射为对象的运行时基础结构. LINQ TO SQL是通过将关系数据库对象的数据模型(如一个数 ...
- LINQ to SQL大全
LINQ to SQL语句 (1)之Where Where操作 适用场景:实现过滤,查询等功能. 说明:与SQL命令中的Where作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的 ...
随机推荐
- jvisualvm 工具使用【转】
VisualVM 是Netbeans的profile子项目,已在JDK6.0 update 7 中自带(java启动时不需要特定参数,监控工具在bin/jvisualvm.exe). https:// ...
- MySQL其他和备份
目录 事务 存储引擎 InnoDB存储引擎 数据存储形式 锁的粒度 事务 数据的存储特点 MyISAM存储引擎 数据存储形式 锁的粒度 事务 数据的存储特点 其他 对比与选择 视图 触发器 存储过程 ...
- springMVC or response redirect https
<bean class="org.springframework.web.servlet.view.InternalResourceViewResolver"> < ...
- 转:进程上下文VS中断上下文
源地址:http://www.cnblogs.com/zzx1045917067/archive/2012/12/19/2824552.html 内核空间和用户空间是现代操作系统的两种工作模式,内核模 ...
- if __name__=='__main__'使用场景,彻底明白
本博中有一篇文章写了 if __name__=='__main__'的作用与原理http://www.cnblogs.com/fennudexiaoniao/p/7458324.html,但是好像似懂 ...
- Java学习之一(引用相关)
1.Java概述 首先,Java是一门面向对象的编程语言.相对于C/C++等语言,Java中没有指针,但是这不代表指针等知识不重要:Java中不存在多继承但是存在多接口.在我自己的学习过程之中,我偏向 ...
- python 第三方库的安装方法
一.看更大的python世界 python 全球计算生态的主站:python 社区 www.pypi.org 二.安装第三方库 1) pip 命令安装方法 1.1 安装第三方库 命令行输入pip in ...
- Pandas系列-读取csv/txt/excel/mysql数据
本代码演示: pandas读取纯文本文件 读取csv文件 读取txt文件 pandas读取xlsx格式excel文件 pandas读取mysql数据表 import pandas as pd 1.读取 ...
- python 将值相同的key分组的方法
方法一: 使用 itertools.groupby() rows = [ {'address': '5412 N CLARK ', 'date ': '07/12/2012 ’ }, {'addres ...
- <每日一题>题目29:五个数字能组成多少互不重复的四位数
#有五个数字:1.2.3.4.5,能组成多少个互不相同且无重复数字的四位数?各是多少? e =[] for a in range(1,6): for b in range(1,6): for c in ...