介绍:
在软件开发中,把数据从一个地方复制到另一个地方是一个普遍的应用。 在很多不同的场合都会执行这个操作,包括旧系统到新系统的移植,从不同的数据库备份数据和收集数据。 ASP.NET 2.0有一个SqlBulkCopy类,它可以帮助你从不同的数据源复制数据到SQL SERVER数据库。 本文中我将示范SqlBulkCopy类的不同应用。

数据库设计: 
这个数据库的设计还是蛮简单的,它基于Northwind数据库的Products表。另外我还在Northwind数据库中创建了3个表。 详情可以看一下下面的数据库关系图。 

        Products_Archive 和Products_Latest有与Products表相同的结构,而Products_TopSelling表则与它们不同。 稍后我将在本文解释Products_TopSelling表的用途。
 
Products_Archive表包含770,000行。 你不用管这些数据是如何得到的,你只需要考虑如何把所有这些数据复制到Products_Latest表里。
从Products_Archive表 复制数据到 Products_Latest表:
SqlBulkCopy 包含一个方法 WriteToServer,它用来从数据的源复制数据到数据的目的地。 WriteToServer方法可以处理的数据类型有DataRow[]数组,DataTable 和 DataReader。 你可以根据不同的情形使用不同的数据类型,但是更多时候选择DataReader是一个比较好的主意。 这是因为DataReader是一个只向前的、只读的数据流,它不会保存数据,所以要比DataTable 和 DataRows[]都要快。 下面的代码的作用是把数据从源表复制到目的表。
 
private static void PerformBulkCopy()    

    string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true"; 
                                                 
    // 源    
    using (SqlConnection sourceConnection = new SqlConnection(connectionString)) 
    { 
        SqlCommand myCommand = new SqlCommand("SELECT * FROM Products_Archive", sourceConnection); 
        sourceConnection.Open(); 
        SqlDataReader reader = myCommand.ExecuteReader();    
                                 
        // 目的    
        using (SqlConnection destinationConnection = new SqlConnection(connectionString)) 
        { 
            // 打开连接    
            destinationConnection.Open(); 
                                 
            using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString)) 
            { 
                bulkCopy.BatchSize = 500; 
        bulkCopy.NotifyAfter = 1000; 
                bulkCopy.SqlRowsCopied += new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied); 
                bulkCopy.DestinationTableName = "Products_Latest"; 
                bulkCopy.WriteToServer(reader);                                         
            } 
        } 
 
        reader.Close();                                    
                                 
    }                     
}
这里有一对需要提及的知识点。 首先,我使用DataReader来从数据库的表中读取数据。 Products_Latest是目的表,因为数据要从Products_Archive表复制到Products_Latest表。 bulkCopy对象提供了一个SqlRowCopied事件,在每次处理完NotifyAfter属性指定的行数时发生。 本例中的意思就是每处理完1000行就触发一次该事件,因为NotifyAfter被设置成了1000
 
BatchSize属性是非常重要的,程序性能如何主要就依靠着它。 BatchSize的意思就是同每一批次中的行数,在每一批次结束时,就将该批次中的行发送到数据库。 我将BatchSize设置成了500,其意思就是reader每读出500行就将他们发送到数据库从而执行批量复制的操作。 BatchSize的默认值是“1”,其意思就是把每一行作为一个批次发送到数据库。
 
设置不同的BatchSize在性能上将给你带来不同的结果。 你应该根据你的需求进行测试,来决定BatchSize的大小。
在不同的映射表之间复制数据
在上面的例子中两个表具有相同的结构。 有时,你需要在具有不同结构的表之间复制数据。 假如你要从Products_Archive表中把所有的产品名称及其数量复制到Products_TopSelling表里。 这两个表有着不同的字段名,具体可以看一下上面的“数据库设计”一节下的。
 
private static void PerformBulkCopyDifferentSchema() 

    string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true"; 
 
    DataTable sourceData = new DataTable(); 
 
    // 源    
    using (SqlConnection sourceConnection = new SqlConnection(connectionString)) 
    { 
        SqlCommand myCommand = new SqlCommand("SELECT TOP 5 * FROM Products_Archive", sourceConnection); 
        sourceConnection.Open(); 
        SqlDataReader reader = myCommand.ExecuteReader(); 
 
        // 目的 
        using (SqlConnection destinationConnection = new SqlConnection(connectionString)) 
        { 
            // 打开连接 
            destinationConnection.Open(); 
 
            using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString)) 
            { 
                bulkCopy.ColumnMappings.Add("ProductID", "ProductID"); 
                bulkCopy.ColumnMappings.Add("ProductName", "Name"); 
                bulkCopy.ColumnMappings.Add("QuantityPerUnit", "Quantity"); 
                bulkCopy.DestinationTableName = "Products_TopSelling"; 
                bulkCopy.WriteToServer(reader); 
            } 
        } 
 
        reader.Close(); 
 
    } 
}
ColumnMappings集合用于映射源表和目的表之间的列。
从XML文件复制数据到数据库的表中
数据源并不局限于数据库的表,你也可以使用XML文件做数据源。 这里有一个非常简单的使用XML文件做数据源进行批量复制操作的例子。 
(Products.xml)
<?xml version="1.0" encoding="utf-8" ?> 
<Products> 
    <Product productID="1" productName="Chai" /> 
    <Product productID="2" productName="Football" /> 
    <Product productID="3" productName="Soap" /> 
    <Product productID="4" productName="Green Tea" /> 
</Products>
 
private static void PerformBulkCopyXMLDataSource() 

    string connectionString = @"Server=localhost;Database=Northwind;Trusted_Connection=true"; 
 
    DataSet ds = new DataSet(); 
    DataTable sourceData = new DataTable();    
    ds.ReadXml(@"C:Products.xml"); 
 
    sourceData = ds.Tables[0]; 
 
    // 目的    
    using (SqlConnection destinationConnection = new SqlConnection(connectionString)) 
    { 
        // 打开连接    
        destinationConnection.Open(); 
 
        using (SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection.ConnectionString)) 
        { 
            // 列映射 
            bulkCopy.ColumnMappings.Add("productID", "ProductID"); 
            bulkCopy.ColumnMappings.Add("productName", "Name"); 
                                         
            bulkCopy.DestinationTableName = "Products_TopSelling"; 
            bulkCopy.WriteToServer(sourceData); 
        } 
    } 
}

首先把XML文件读进DataTable,然后再使用SqlBulkCopy类的WriteToServer方法。 因为目的表示是Products_TopSelling,所以我们必须执行列映射。

结论 
本文中我示范了如何使用.NET 2.0引入的SqlBulkCopy类。 SqlBulkCopy类可以非常简单的把数据从一个数据源复制到SQL SERVER数据库。

使用asp.net 2.0中的SqlBulkCopy类批量复制数据的更多相关文章

  1. 用.net中的SqlBulkCopy类批量复制数据 (转载)

    在软件开发中,把数据从一个地方复制到另一个地方是一个普遍的应用. 在很多不同的场合都会执行这个操作,包括旧系统到新系统的移植,从不同的数据库备份数据和收集数据. .NET 2.0有一个SqlBulkC ...

  2. C# 使用 SqlBulkCopy 类批量复制数据到数据库

    最近公司需要优化导入的问题,由于之前使用的方式是生成 Insert 语句插入数据库,数据量小的时候还行,但是随着发展数据量渐渐大了,之前的方法性能就跟不上了,于是发现了 SqlBulkCopy 这个类 ...

  3. C# 使用SqlBulkCopy类批量复制大数据

    用途说明: 前些日子,公司要求做一个数据导入程序,要求将Excel数据,大批量的导入到数据库中,尽量少的访问数据库,高性能的对数据库进行存储.于是在网上进行查找,发现了一个比较好的解决方案,就是采用S ...

  4. C# SqlBulkCopy类批量导入数据

    特别注意  sqlbulkcopy.ColumnMappings.Add(dt.Columns[i].ColumnName, dt.Columns[i].ColumnName); 插入的时候列的顺序可 ...

  5. 使用SqlBulkCopy类批量复制大数据

    using System; using System.Configuration; using System.Data; using System.Data.SqlClient; using Syst ...

  6. 转:SqlBulkCopy类进行大数据(一万条以上)插入测试

    转自:https://www.cnblogs.com/LenLi/p/3903641.html 结合博主实例,自己测试了一下,把数据改为3万行更明显!! 关于上一篇博客中提到的,在进行批量数据插入数据 ...

  7. SqlBulkCopy类进行大数据(一万条以上)插入测试

    好多天没写博客了,刚刚毕业一个多月! 关于上一篇博客中提到的,在进行批量数据插入数据库的时候可以通过给存储过程传递一个类型为Table的参数进行相关操作,在这个过程中本人没有进行效率的测试.后来查找发 ...

  8. SqlBulkCopy类进行大数据(10000万条以上)插入测试

    好多天没写博客了,刚刚毕业一个多月,在IT的路上真是迷茫啊! 关于上一篇博客中提到的,在进行批量数据插入数据库的时候可以通过给存储过程传递一个类型为Table的参数进行相关操作,在这个过程中本人没有进 ...

  9. asp.net 2.0中新增的web.config的默认namespace功能 (转)

    看上去这个题目比较长,但实际上,我在看资料时发现,这就是说,在asp.net 2.0中,只需要在web.config里定义你要用的那些namespace,则在aspx页面中就不需要再象1.1那样,用 ...

随机推荐

  1. Http请求中 content-type 和 dataType 区别

    contentType: 告诉服务器,我要发什么类型的数据 dataType:告诉服务器,我要想什么类型的数据,如果没有指定,那么会自动推断是返回 XML,还是JSON,还是script,还是Stri ...

  2. 三、u-boot 的配置-mkconfig 脚本

    3.1 mkconfig 脚本 100ask24x0_config : unconfig @$(MKCONFIG) $(@:_config=) arm arm920t 100ask24x0 NULL ...

  3. oracle sum(x) over( partition by y ORDER BY z ) 分析

    之前用过row_number(),rank()等排序与over( partition by ... ORDER BY ...),这两个比较好理解: 先分组,然后在组内排名. 今天突然碰到sum(... ...

  4. Vue.js用脚手架创建项目

    安装全局脚手架 cnpm install vue-cli -g vue --version 用脚手架创建项目 创建项目 运行项目 停止项目:Ctrl+C 修改端口 config - index.js ...

  5. char *a与char a[n]的区别

    char *a='ab';//a[2]一定为'\0',但是,a[5]这样的指针越界不会报错 char a[3] = {'a','a','a'};//a[3]属于越界,会报错 char b[5]={'b ...

  6. 实例详析ImageView的adjustViewBonds和scaleType

    android:adjustViewBounds是否保持宽高比.需要与maxWidth.MaxHeight一起使用,否则单独使用没有效果. 设置View的最大高度,单独使用无效,需要与setAdjus ...

  7. Three.js基础探寻一

    1.webGL 一种网络标准,定义了一些较底层的图形接口. 2.Three.js 一个3Djs库,webGL开源框架中比较优秀的一个.除了webGL以外,Three.js还提供了基于Canvas.SV ...

  8. Paramiko 操作远端时无法切换目录的问题

    最近在用Paramiko 开发一款远程测试调试框架,结果发现目录怎么都无法切换,查了下原因,在http://bbs.chinaunix.net/thread-1675446-1-1.html看到了 P ...

  9. zabbix系列(四)Zabbix3.0.4添加对Nginx服务的监控

    Zabbix3.0.4添加对Nginx服务的监控 通过Nginx的http_stub_status_module模块提供的状态信息来监控,所以在Agent端需要配置Nginx状态获取的脚本,和添加ke ...

  10. Android软件更新

    Android软件更新 //得到当前版本编码和版本名称. public static int getVerCode(Context context) { ; try { verCode =).vers ...