第二十一节: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的无状态模 ...
随机推荐
- 记录Nginx模块开发
--with-http_stub_status_module模块:Nginx的客户端状态 Syntax:stub_status Default:-- Content:server,location l ...
- Spring Boot 2.x 快速入门(上)HelloWorld示例
本文重点 最近决定重新实践下Spring Boot的知识体系,因为在项目中遇到的总是根据业务需求走的知识点,并不能覆盖Spring Boot完整的知识体系,甚至没有一个完整的实践去实践某个知识点.最好 ...
- Java MultipartFile 使用记录
private void file(String path,MultipartFile file){ String separator = "/"; String originFi ...
- Logging 日志配置格式模板
import osBASE_DIR = os.path.dirname(os.path.dirname(__file__))DB_PATH = os.path.join(BASE_DIR, 'db') ...
- final和static关键字
1.如果类只有静态方法,可以将构造函数标记为private以避免被初始化: 2.常量同时标记为static和final,常量名全部大写,下划线连接: 3.final修饰一个成员变量(属性),必须要显示 ...
- OpenStack-Nova(4)
一. Nova概述 使用OpenStack Compute来托管和管理云计算系统.OpenStack Compute是基础架构即服务(IaaS)系统的主要部分.主要模块在Python中实现. Open ...
- Zookeeper 客户端命令
- PHP 5.0~5.6 各版本兼容性的 cURL 文件上传
不同版本PHP之间cURL的区别 PHP的cURL支持通过给CURL_POSTFIELDS传递关联数组(而不是字符串)来生成multipart/form-data的POST请求. 传统上,PHP的cU ...
- Mac之brew使用
brew : 终端程序管理工具 能让你更快速的安装你想要的工具.而不用考虑大量的依赖. 安装命令 给官网的一样也可以自己去官网查看 它就类似于centos下的yum 和 Ubuntu下的apt-get ...
- vue中使用Base64和md5和rsa
https://blog.csdn.net/benben513624/article/details/88113459(copy) https://www.cnblogs.com/myfate/p/1 ...