无论是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. npm淘宝镜像配置

    npm config set registry https://registry.npm.taobao.org

  2. loj6094 归乡迷途

    题意:有一张n个点的无向图,点有标号.求满足下列性质的图有多少个. 1.任意节点到1的最短路唯一.2.i的最短路长度<=i+1的最短路长度.3.所有点的度数给定,为2或3. n<=400. ...

  3. 关于Mysql几周的整理文档

    https://files.cnblogs.com/files/swobble/mysql.rar 内容包括 版本测试(5.5,5.6,5.7) 平台测试(windows所有平台) 文件说明 精简说明 ...

  4. 深入浅出Mybatis系列(六)---objectFactory、plugins、mappers简介与配置[转]

    上篇文章<深入浅出Mybatis系列(五)---TypeHandler简介及配置(mybatis源码篇)>简单看了一下TypeHandler, 本次将结束对于mybatis的配置文件的学习 ...

  5. ubuntu挂载和挂载NTFS分区命令

    1.挂载 首先安装NTFS-3g,不过Ubuntu一般自带: sudo apt install ntfs-3g 查看分区信息: sudo fdisk -l 结果类似: /dev/sda1  *     ...

  6. 微信小程序连续旋转动画this.animation.rotate

    一..js中封装旋转动画方法 添加animation属性 data:{ animation:''" } 改变animation的值(官网提供角度范围是-180~180,但是我发现角度越大会一 ...

  7. Genymotion 的那些事

    一.什么是Genymotion? Genymotion是一套完整的工具,它提供了Android虚拟环境. 支持Windows.Linux和Mac OS等操作系统. 在Android开发中可以代替安卓模 ...

  8. 解决编译GCC内存不足的错误

    近期在使用阿里和腾讯的云服务器,由于只是测试用所以只租用了廉价512的内存,在编译gcc时遇到错误,表面上看只是编译错误,并且原因不明,纠结了几次之后猜测应该是由于系统资源不足导致的,所以尝试增加系统 ...

  9. java实现从实体到SQL语句的转换

    使用过Hibernate,EF之类的ORM框架都知道一般的CRUD之类的简单操作,只要调用框架封装好了的方法,框架就自动生成相应的SQL语句了,参照实习公司给的代码,那个是C#版的,今天弄了一下jav ...

  10. List循环添加对象时遇到问题的解决

    var temp=new handleData(); foreach(var t in data) { temp.DataValue = t.DataValue; temp.CreateTime = ...