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作用相似,都是起到范围限定也就是过滤作用的,而判断条件就是它后面所接的 ...
随机推荐
- QSerialPort类
一.简介 QSerialPort类是Qt5封装的串口类,可以与串口进行通信.QSerialPortInfo是一个辅助类,提供串口的一些信息,如可用的串口名称,描述,制造商,序列号,串口16位产 ...
- vertx使用过程中浏览器端Cookie重复问题
[问题描述] 背景: 使用vertx提供的服务,使用Dispatcher做路由转发,内部通过routingcontext做请求传递及响应. 现象: 在谷歌浏览器的Network中,看到Cookie中有 ...
- 淼一淼A+B problem
鲁迅:这可是道难题呢! 鲁迅:我没说过这话,不过确实在理. 某改题毕,但见LOJ之上有数「A+B」之AC记录.余亦尝闻A+B之趣味无穷,遂兴起而码之. 少顷,AC之,吾心所畅. #include< ...
- Django简介以及安装
目录 前言 Web框架本质 服务器和应用程序 基于第三方模块实现Web框架 Python三大主流Web框架 django flask tornado Django框架介绍 安装 创建项目 创建App ...
- 2-sat——hdu3062基础
hdu就是会卡cin,, 另一种建模方式,把点i拆成i*2,i*2+1,有时候这样会比较简单 #include<bits/stdc++.h> using namespace std; #d ...
- dijkstra (模板)
突然意识到以前写的都是假的dij,感谢GhostCai神犇. #include<iostream> #include<cstdio> #include<cstring&g ...
- ssh 与服务器保持连接
直接改客户端,服务器端不应该更改. sudo vi /etc/ssh/ssh_config # 或 ~/.ssh/config TCPKeepAlive=yes # Client每隔 60 秒发送一次 ...
- js 倒计时毫秒级别显示
<html> <head> <style> div{ width:100%; text-align:center; font-size: 14px; } </ ...
- Leetcode319. Bulb Switcher灯泡开关
初始时有 n 个灯泡关闭. 第 1 轮,你打开所有的灯泡. 第 2 轮,每两个灯泡你关闭一次. 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭).第 i 轮,每 i 个灯泡切换一次 ...
- 11.Hibernate一对多关系
创建JavaBean 一方: Customer private long cust_id; private String cust_name; private long cust_user_id; p ...