无论是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. QSerialPort类

    一.简介     QSerialPort类是Qt5封装的串口类,可以与串口进行通信.QSerialPortInfo是一个辅助类,提供串口的一些信息,如可用的串口名称,描述,制造商,序列号,串口16位产 ...

  2. vertx使用过程中浏览器端Cookie重复问题

    [问题描述] 背景: 使用vertx提供的服务,使用Dispatcher做路由转发,内部通过routingcontext做请求传递及响应. 现象: 在谷歌浏览器的Network中,看到Cookie中有 ...

  3. 淼一淼A+B problem

    鲁迅:这可是道难题呢! 鲁迅:我没说过这话,不过确实在理. 某改题毕,但见LOJ之上有数「A+B」之AC记录.余亦尝闻A+B之趣味无穷,遂兴起而码之. 少顷,AC之,吾心所畅. #include< ...

  4. Django简介以及安装

    目录 前言 Web框架本质 服务器和应用程序 基于第三方模块实现Web框架 Python三大主流Web框架 django flask tornado Django框架介绍 安装 创建项目 创建App ...

  5. 2-sat——hdu3062基础

    hdu就是会卡cin,, 另一种建模方式,把点i拆成i*2,i*2+1,有时候这样会比较简单 #include<bits/stdc++.h> using namespace std; #d ...

  6. dijkstra (模板)

    突然意识到以前写的都是假的dij,感谢GhostCai神犇. #include<iostream> #include<cstdio> #include<cstring&g ...

  7. ssh 与服务器保持连接

    直接改客户端,服务器端不应该更改. sudo vi /etc/ssh/ssh_config # 或 ~/.ssh/config TCPKeepAlive=yes # Client每隔 60 秒发送一次 ...

  8. js 倒计时毫秒级别显示

    <html> <head> <style> div{ width:100%; text-align:center; font-size: 14px; } </ ...

  9. Leetcode319. Bulb Switcher灯泡开关

    初始时有 n 个灯泡关闭. 第 1 轮,你打开所有的灯泡. 第 2 轮,每两个灯泡你关闭一次. 第 3 轮,每三个灯泡切换一次开关(如果关闭则开启,如果开启则关闭).第 i 轮,每 i 个灯泡切换一次 ...

  10. 11.Hibernate一对多关系

    创建JavaBean 一方: Customer private long cust_id; private String cust_name; private long cust_user_id; p ...