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作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的 ...
随机推荐
- css3 html5 手机设备 列表的弹回和加速移动
<style type="text/css"> * { margin: 0; padding: 0; } .min { width: 350px; height: 40 ...
- 第二章计算机网络ios 模型
机构: ISO国际标准化组织: ITU国际电信联盟: ANSI 美国国家标准委员会: ECMA欧洲计算机制作商协会 ITEF因特网特别任务组. 协议:为计算机网路中进行数据交换而建立的规则,标准或约定 ...
- 【10.6NOIP普及模拟】MATH——枚举法
[10.6NOIP普及模拟]MATH 题目简化 一个数列任意删k个数,是得数列中最大的差+最小的差最小 思路 程序1--时超40 暴搜+剪枝. 用类似排列组合的方式,暴搜删或不删 剪枝就是看看剩下的数 ...
- day08 网络设置、软件包管理
网络设置 ifconfig //最小化安装时不可用,需要安装安装包,命令为查看网卡信息 yum install net-tools mtu 网卡的最大发送字节 iptables -F 清掉防火墙配置 ...
- codeforces 1100E-Andrew and Taxi
传送门:QAQQAQ 题意:给你一个图,每条边有边权,现在你可以对边进行反转,使图中不存在环,你需要使得反转的边的边权集合中的最大值最小,并输出任意一组解. 思路:二分+拓扑排序 使得最大值最小,自然 ...
- Undertow服务器基础分析 - XNIO
阅读更多 我们从名字上就能看出这是一个NIO思想为基础的IO框架,X是指这个框架可以有多种实现,我们可以从代码库 https://github.com/xnio 中发现一个项目xnio-native, ...
- mysql表时间戳字段设置
创建时间 修改时间
- vim 插入行号
:let i=1000000|g/^/s//\=i.' '/|let i=i+1
- c++设计模式:观察者模式
主要思想:建立一个一对多的关系,当一个对象发生发生变化时,其他对象也发生变化. 可以举个博客订阅的例子,当博主发表新文章的时候,即博主状态发生了改 变,那些订阅的读者就会收到通知,然后进行相应的动作, ...
- 19-10-24-J-快乐?
向未来的大家发送祝福(不接受的请自动忽略): 祝大家程序员节快乐! 好了. ZJ一下 额. 考场上差点死了. 码1h后,T1还没过大样例. 我×××. 后来发现是自己××了. T2T3丢暴力. 比咕的 ...