一. 简介

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类插入和更新)的更多相关文章

  1. 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配 ...

  2. 风炫安全WEB安全学习第二十一节课 存储型XSS讲解

    风炫安全WEB安全学习第二十一节课 存储型XSS讲解 存储型XSS演示 存储型XSS,持久化,代码是存储在服务器中的,如在个人信息或发表文章等地方,加入代码,如果没有过滤或过滤不严,那么这些代码将储存 ...

  3. 第二十一节,使用TensorFlow实现LSTM和GRU网络

    本节主要介绍在TensorFlow中实现LSTM以及GRU网络. 一 LSTM网络 Long Short Term 网络—— 一般就叫做 LSTM ——是一种 RNN 特殊的类型,可以学习长期依赖信息 ...

  4. 【php增删改查实例】第二十一节 - 用户修改功能

    19.1 添加用户修改的按钮 打开userManage.html,找到新增按钮的地方: 我们不难发现,编辑按钮就差不多应该在新建用户的右边. 那么,假如我现在是新人,对这个项目本身就不太熟悉,那么我得 ...

  5. 第二十一节:Asp.Net Core MVC和WebApi路由规则的总结和对比

    一. Core Mvc 1.传统路由 Core MVC中,默认会在 Startup类→Configure方法→UseMvc方法中,会有默认路由:routes.MapRoute("defaul ...

  6. [ExtJS5学习笔记]第二十一节 Extjs5中使用config配置给ext.widget或者create方法传递参数

    本文地址:http://blog.csdn.net/sushengmiyan/article/details/39252805 官方例子:http://docs.sencha.com/extjs/5. ...

  7. 第二十一节:Java语言基础-关键字,标识符,注释,常量和变量,运算符

    Java语言基础-关键字,标识符,注解,常量和变量,运算符 class Demo { public static void main(String[] args){ System.out.printl ...

  8. php第二十一节课

    AJAX <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3 ...

  9. 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的无状态模 ...

随机推荐

  1. Filebeat插件启动失败,不能直接查找报错原因

    老是在filebeat启动的这一步骤上出错,但是由于filebeat是由systemd启动的,因此原因也经常查不清楚,因此并不能直观的查出错误在哪里,所以今天教给大家两个寻找错误的根源的方法 先看我这 ...

  2. Maven构建项目出现No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK?

    No compiler is provided in this environment. Perhaps you are running on a JRE rather than a JDK? 你应该 ...

  3. jQuery each、节点操作、动画演示、尺寸操作、扩展方法

    一.each 1.方式一:$.each(数组或者自定义对象,function(i,j){console.log(i,j)}) $.each(li,function(i,j){ console.log( ...

  4. .net 获取远程访问的ip

    这两天一直做获取远程访问的ip和自己的ip相关的问题. 在解决获取ip相关问题的时候,主要使用了上下文对象,httpcontext对象.原理很简单,内部有两大对象,request和response.里 ...

  5. 《通过C#学Proto.Actor模型》之Spawning

    Props是配置Actor和实例化Actor,那实例化后,就应该访问了,Props.Actor提供了Actor.Spawn(),Actor.SpawnPrefix(),Actor.SpawnNamed ...

  6. SpringMVC项目读取不到外部CSS文件的解决办法及总结

    昨天,在写一个新需求的时候,因为没有前端同事的对接,无奈只有自己写css,js放到ssm结构的后台项目中,因为之前开发都是把前端文件放在一个专门的服务器上,一直没有关注服务端项目读取静态资源的问题,运 ...

  7. System.getProperty System.getenv 区别 log4j取法

    log4j 可以${}取系统变量相关属性  getProperty Java提供了System类的静态方法getenv()和getProperty()用于返回系统相关的变量与属性,getenv方法返回 ...

  8. HttpServletRequest get

    假设客户端请求的地址:http://localhost:8082/TestReq/MyServlet/username=李雷&age=20 request.getRequestURL http ...

  9. svn 钩子应用 - svn 提交字符限制, 不能为空

    一.版本库钩子 1.1 start-commit  开始提交的通知 输入参数:传递给你钩子程序的命令行参数,顺序如下: 1.  版本库路径 2.  认证过的尝试提交的用户名 3.  Depth,mer ...

  10. easyui-tab标签

    一. 加载方式 //class 加载方式<div id="box" class="easyui-tabs" style="width:500px ...