博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
将不确定变为确定系列~Linq的批量操作靠的住吗?
阅读量:6433 次
发布时间:2019-06-23

本文共 4632 字,大约阅读时间需要 15 分钟。

无论是Linq To SQL还是Linq To Object(Entity frameworks)它们都为开发人员提供了Insert操作,及Insert集合操作,即InsertOnSubmit和InsertAllOnSubmit,前者是将一个实体标记为一个插入状态,而后都是将一个集合标记为插入状态,而当前进行这两种操作时,你并没有与数据库进行连接,这就是LINQ提倡的延时加载,那它们什么时候与数据库进行真正的交互呢,实现上,实验表明,是在触发SubmitChanges方法时,才会真实与数据库进行操作,这是正常的,也没有什么可以说的。

      而今天我主要说的就是,当我们进行批量插入时,用linq给我们提供的InsertAllOnSubmit方法是否可以实现我们的操作,如果实现了,那是否是我们能够接受的方式,我们在做一个实验吧

一个列表:

1 List
userList=new List
();2 3 for(int i=0;i<100000;i++)4 {5 userList.Add(new User{Name="zzl"+i});6 }7 _db.InsertAllOnSubmit(userList);8 9 _db.SubmitChanges();

结果怎么样呢?经过我的观察,结果是正确的,10万条数据可以插入到数据库中,LINQ确实是帮助我们完成了列表的插入工作,但过程我们是否可以接受?

可以肯定的说,不可以,而且是非常不可以,对于这个插入操作,它对数据服务器的压力是惊人的,它建立“链接”次为10万次,即每个Insert语句就建立一个链接,这是我们不能接受的,所以,LINQ的批量操作确实靠不住。

OK,既然LINQ的方式是不可取的,那我们只好自己去动手写了,呵呵,我们的思想去将10条Insert合并在一起,一次性发给服务器,一次性执行,对于目前的网络带宽这10条数据不成问题,呵呵。

一 单个实体的Insert,我们采用LINQ的延时插入方式:

1  public virtual void Insert
(TEntity entity) where TEntity : class2 {3 DB.GetTable
().InsertOnSubmit(entity);4 this.SubmitChanges();5 }

二 批量插入实体,我们采用拼接字符串,并向数据服务器发命令的方式,这个也是我比较满足的作品,它是一个通用的方式,并且不需要修改原来插入代码,它的

方法签名是一个列表,这样做是正确的,对于程序员来说是非常友好的。

先看之前的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 : class7 {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
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 else50 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
(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
insert = CreateInsertArguments(i);73 sqlstr.AppendFormat(insert.Item1, insert.Item2);74 });75 DB.ExecuteCommand(sqlstr.ToString());76 }77 78 #endregion

接下来的时间,我将会继续写一个批量更新和批量删除,敬请收看,呵呵。

本文转自博客园张占岭(仓储大叔)的博客,原文链接:,如需转载请自行联系原博主。

你可能感兴趣的文章
Java在线调试工具
查看>>
[译]CSS-理解百分比的background-position
查看>>
虚拟机安装CentOS
查看>>
Idea里面老版本MapReduce设置FileInputFormat参数格式变化
查看>>
在 win10 环境下,设置自己写的 程序 开机自动 启动的方法
查看>>
Unity3d游戏开发之-单例设计模式-多线程一
查看>>
Java 程序员必备的 15 个框架,前 3 个地位无可动摇!
查看>>
构建MySQL自动化平台思路
查看>>
通过jquery定位元素
查看>>
Tooltip表单验证的注册表单
查看>>
UWP开发中两种网络图片缓存方法
查看>>
超8千Star,火遍Github的Python反直觉案例集!
查看>>
【msdn wpf forum翻译】如何在wpf程序(程序激活时)中捕获所有的键盘输入,而不管哪个元素获得焦点?...
查看>>
全球首家!阿里云获GNTC2018 网络创新大奖 成唯一获奖云服务商
查看>>
Python简单HttpServer
查看>>
Java LinkedList工作原理及实现
查看>>
负载均衡SLB的基本使用
查看>>
Centos 7 x86 安装JDK
查看>>
微信小程序的组件用法与传统HTML5标签的区别
查看>>
Hangfire 使用笔记
查看>>