使用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数据库。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值