第二十一节:ADO层次上的海量数据处理方案(SqlBulkCopy类插入和更新)
一. 简介
1. 背景:
虽然前面EF的扩展插件Z.EntityFramework.Extensions,性能很快,而且也很方便,但是该插件要收费,使用免费版本的话,需要定期更新,如果不更新,将失效,非常麻烦,这个时候SqlBulkCopy类既免费又高效,显得非常合适了。
2. 使用步骤:
①. 引入命名空间:using System.Data.SqlClient;
②. 使用DataTable构造与目标数据库表结构相同的字段,并给其赋值。
③. 使用SqlBulkCopy类,将内存表中的数据一次性插入到目标表中。(看下面的封装可知,可以自行设置插入块的大小)
补充:调用下面的封装这种形式必须内存表中的字段名和数据库表中的字段名一一对应。
二. 使用方式及其性能测试
1. 涉及到的数据库结构:

2. 数据库连接字符串
<add name="CodeFirstModel2" connectionString="data source=localhost;initial catalog=EFDB2;persist security info=True;user id=sa;password=123456;MultipleActiveResultSets=True;App=EntityFramework" providerName="System.Data.SqlClient" />
3. 代码实践
有两种插入方式,一种是按部就班的每个字段 内存表和数据表进行映射,这个情况无须名称一致,只要映射正确即可。另外一种方式是,直接调用下面的封装方法即可,这种要求内存表中字段和数据库表中的字段名称必须完全一致,一一对应,这样就省去了方法一 中一一匹配映射的繁琐步骤了。
public class SqlBulkCopyTest
{
public static void TestSqlBulkCopy()
{
//一. 构造DataTable结构并且给其赋值
//1.定义与目标表的结构一致的内存表 排除自增id列
DataTable dtSource = new DataTable();
//列名称如果和目标表设置为一样,则后面可以不用进行字段映射
dtSource.Columns.Add("id");
dtSource.Columns.Add("t21");
dtSource.Columns.Add("t22");
//2. 向dt中增加4W条测试数据
DataRow dr;
for (int i = ; i <; i++)
{
// 创建与dt结构相同的DataRow对象
dr = dtSource.NewRow();
dr["id"] = Guid.NewGuid().ToString("N");
dr["t21"] = "Name" + i;
dr["t22"] = "Address" + i;
// 将dr追加到dt中
dtSource.Rows.Add(dr);
}
//二.将内存表dt中的4W条数据一次性插入到t_Data表中的相应列中
System.Diagnostics.Stopwatch st = new System.Diagnostics.Stopwatch();
st.Start();
string connStr = ConfigurationManager.ConnectionStrings["CodeFirstModel2"].ToString(); #region 01-按部就班一一对应
//{
// using (SqlBulkCopy copy = new SqlBulkCopy(connStr))
// {
// //1 指定数据插入目标表名称
// copy.DestinationTableName = "TestTwo"; // //2 告诉SqlBulkCopy对象 内存表中的 字段和目标表中的字段 对应起来(这里有多个重载,也可以用索引对应)
// //前面是内存表,后面是目标表即数据库中的字段
// copy.ColumnMappings.Add("id", "id");
// copy.ColumnMappings.Add("t21", "t21");
// copy.ColumnMappings.Add("t22", "t22"); // //3 将内存表dt中的数据一次性批量插入到目标表中
// copy.WriteToServer(dtSource);
// }
//} #endregion #region 02-调用封装
{
AddByBluckCopy(connStr, dtSource, "TestTwo");
}
#endregion st.Stop();
Console.WriteLine("数据插入成功,总耗时为:" + st.ElapsedMilliseconds + "毫秒"); } /// <summary>
/// 海量数据插入方法
/// (调用该方法需要注意,DataTable中的字段名称必须和数据库中的字段名称一一对应)
/// </summary>
/// <param name="connectstring">数据连接字符串</param>
/// <param name="table">内存表数据</param>
/// <param name="tableName">目标数据的名称</param>
public static void AddByBluckCopy(string connectstring,DataTable table, string tableName)
{
if (table != null && table.Rows.Count > )
{
using (SqlBulkCopy bulk = new SqlBulkCopy(connectstring))
{
bulk.BatchSize = ;
bulk.BulkCopyTimeout = ;
bulk.DestinationTableName = tableName;
bulk.WriteToServer(table);
}
}
}
}
4. 性能测试的结论

根据上述的数据测试可以看出来,SqlBulkCopy在处理大数据量插入上速度非常快,甚至比付费的插件Z.EntityFramework.Extensions都要快,所以值得参考和推荐。
既然SqlBulkCopy解决大数据量的插入问题,那么删除和更新怎么办呢? 详见 第二十三节: EF性能篇(三)之基于开源组件 Z.EntityFrameWork.Plus.EF6解决EF性能问题
!
- 作 者 : Yaopengfei(姚鹏飞)
- 博客地址 : http://www.cnblogs.com/yaopengfei/
- 声 明1 : 本人才疏学浅,用郭德纲的话说“我是一个小学生”,如有错误,欢迎讨论,请勿谩骂^_^。
- 声 明2 : 原创博客请在转载时保留原文链接或在文章开头加上本人博客地址,如需代码请留下你的评论,加我QQ:604649488 (备注:评论的博客名)
第二十一节:ADO层次上的海量数据处理方案(SqlBulkCopy类插入和更新)的更多相关文章
- centos LAMP第三部分php,mysql配置 php配置文件 配置php的error_log 配置php的open_basedir 安装php的扩展模块 phpize mysql配置第二十一节课
centos LAMP第三部分php,mysql配置 php配置文件 配置php的error_log 配置php的open_basedir 安装php的扩展模块 phpize mysql配 ...
- 风炫安全WEB安全学习第二十一节课 存储型XSS讲解
风炫安全WEB安全学习第二十一节课 存储型XSS讲解 存储型XSS演示 存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存 ...
- 第二十一节,使用TensorFlow实现LSTM和GRU网络
本节主要介绍在TensorFlow中实现LSTM以及GRU网络. 一 LSTM网络 Long Short Term 网络—— 一般就叫做 LSTM ——是一种 RNN 特殊的类型,可以学习长期依赖信息 ...
- 【php增删改查实例】第二十一节 - 用户修改功能
19.1 添加用户修改的按钮 打开userManage.html,找到新增按钮的地方: 我们不难发现,编辑按钮就差不多应该在新建用户的右边. 那么,假如我现在是新人,对这个项目本身就不太熟悉,那么我得 ...
- 第二十一节:Asp.Net Core MVC和WebApi路由规则的总结和对比
一. Core Mvc 1.传统路由 Core MVC中,默认会在 Startup类→Configure方法→UseMvc方法中,会有默认路由:routes.MapRoute("defaul ...
- [ExtJS5学习笔记]第二十一节 Extjs5中使用config配置给ext.widget或者create方法传递参数
本文地址:http://blog.csdn.net/sushengmiyan/article/details/39252805 官方例子:http://docs.sencha.com/extjs/5. ...
- 第二十一节:Java语言基础-关键字,标识符,注释,常量和变量,运算符
Java语言基础-关键字,标识符,注解,常量和变量,运算符 class Demo { public static void main(String[] args){ System.out.printl ...
- php第二十一节课
AJAX <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...
- ASP.NET MVC深入浅出系列(持续更新) ORM系列之Entity FrameWork详解(持续更新) 第十六节:语法总结(3)(C#6.0和C#7.0新语法) 第三节:深度剖析各类数据结构(Array、List、Queue、Stack)及线程安全问题和yeild关键字 各种通讯连接方式 设计模式篇 第十二节: 总结Quartz.Net几种部署模式(IIS、Exe、服务部署【借
ASP.NET MVC深入浅出系列(持续更新) 一. ASP.NET体系 从事.Net开发以来,最先接触的Web开发框架是Asp.Net WebForm,该框架高度封装,为了隐藏Http的无状态模 ...
随机推荐
- 浪潮服务器I4008/NX5480M4介绍
浪潮I4008 / NX5480M4是一款高密度模块化服务器. I4008是机箱,NX5480M4是节点. 8个计算节点模块可以部署在标准机架4U高度机器里,具有高性能.低功耗.易维护.组管理功能.适 ...
- LeetCode算法题-Maximum Depth of N-ary Tree(Java实现)
这是悦乐书的第261次更新,第274篇原创 01 看题和准备 今天介绍的是LeetCode算法题中Easy级别的第128题(顺位题号是559).给定n-ary树,找到它的最大深度.最大深度是从根节点到 ...
- ASP.NET MVC学习系列(4)——MVC过滤器FilterAttribute
1.概括 MVC提供的几种过滤器其实也是一种特性(Attribute),MVC支持的过滤器类型有四种,分别是:AuthorizationFilter(授权),ActionFilter(行为),Resu ...
- Hadoop Yarn配置项 yarn.nodemanager.resource.local-dirs探讨
1. What is the recommended value for "yarn.nodemanager.resource.local-dirs"? We only have ...
- 前端面试回顾---javascript的面向对象
转:https://segmentfault.com/a/1190000011061136 前言 前一阵面试,过程中发现问到一些很基础的问题时候,自己并不能很流畅的回答出来.或者遇到一些基础知识的应用 ...
- Mac系统下Mysql存储数据报错 ER_TRUNCATED_WRONG_VALUE_FOR_FIELD: Incorrect string value
比如如下mysql操作插入数据: const mysql = require('mysql'); /* createConnection方法创建一个表示与Mysql数据库服务器之间连接的 Connec ...
- python 获取秒级时间间隔
import datetime,time start_tm=datetime.datetime.now() time.sleep() end_tm=datetime.datetime.now() pr ...
- 利用numpy+matplotlib绘图的基本操作教程
简述 Matplotlib是一个基于python的2D画图库,能够用python脚本方便的画出折线图,直方图,功率谱图,散点图等常用图表,而且语法简单.具体介绍见matplot官网. Numpy(Nu ...
- java oop 集合框架
集合主要是用来存放数据的,集合与数组的主要区别在于,集合的大小不受限制,而数组的大小受限制,在使用集合增加数据时又常常与泛型联系起来,所以集合和泛型在实际开发过程中总会结合在一起 数组致命的缺点是数组 ...
- 关于gitee代码上传下载
1.在gitee上面创建新分支: 2.复制本地ssh秘钥(C:\Users\Administrator\.ssh) 添加到 gitee设置页面的ssh:(如果之前没有秘钥,就执行ssh-keygen ...