使用asp.net 2.0中的SqlBulkCopy类批量复制数据

简介:
  介绍:
在软件开发中,把数据从一个地方复制到另一个地方是一个普遍的应用。 在很多不同的场合都会执行这个操作,包括旧系统到新系统的移植,从不同的数据库备份数据和收集数据。 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数据库。














本文转自周金桥51CTO博客,原文链接:http://blog.51cto.com/zhoufoxcn/166052 ,如需转载请自行联系原作者


相关文章
|
1月前
|
开发框架 .NET C#
C#|.net core 基础 - 删除字符串最后一个字符的七大类N种实现方式
【10月更文挑战第9天】在 C#/.NET Core 中,有多种方法可以删除字符串的最后一个字符,包括使用 `Substring` 方法、`Remove` 方法、`ToCharArray` 与 `Array.Copy`、`StringBuilder`、正则表达式、循环遍历字符数组以及使用 LINQ 的 `SkipLast` 方法。
|
28天前
|
SQL XML 关系型数据库
入门指南:利用NHibernate简化.NET应用程序的数据访问
【10月更文挑战第13天】NHibernate是一个面向.NET的开源对象关系映射(ORM)工具,它提供了从数据库表到应用程序中的对象之间的映射。通过使用NHibernate,开发者可以专注于业务逻辑和领域模型的设计,而无需直接编写复杂的SQL语句来处理数据持久化问题。NHibernate支持多种数据库,并且具有高度的灵活性和可扩展性。
39 2
|
19天前
.NET 4.0下实现.NET4.5的Task类相似功能组件
【10月更文挑战第29天】在.NET 4.0 环境下,可以使用 `BackgroundWorker` 类来实现类似于 .NET 4.5 中 `Task` 类的功能。`BackgroundWorker` 允许在后台执行耗时操作,同时不会阻塞用户界面线程,并支持进度报告和取消操作。尽管它有一些局限性,如复杂的事件处理模型和不灵活的任务管理方式,但在某些情况下仍能有效替代 `Task` 类。
|
1月前
|
API
使用`System.Net.WebClient`类发送HTTP请求来调用阿里云短信API
使用`System.Net.WebClient`类发送HTTP请求来调用阿里云短信API
21 0
|
3月前
|
缓存 程序员
封装一个给 .NET Framework 用的内存缓存帮助类
封装一个给 .NET Framework 用的内存缓存帮助类
|
3月前
|
开发框架 .NET 数据库连接
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
闲话 Asp.Net Core 数据校验(三)EF Core 集成 FluentValidation 校验数据例子
|
4月前
|
开发框架 JSON 前端开发
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
利用查询条件对象,在Asp.net Web API中实现对业务数据的分页查询处理
|
3月前
|
开发框架 前端开发 算法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
分享 .NET EF6 查询并返回树形结构数据的 2 个思路和具体实现方法
|
5月前
|
存储 Go C#
【.NET Core】深入理解IO之File类
【.NET Core】深入理解IO之File类
76 6
|
5月前
|
存储 开发框架 缓存
【.NET Core】你真的了解HttpRuntime类吗
【.NET Core】你真的了解HttpRuntime类吗
47 0