65.9K
CodeProject 正在变化。 阅读更多。
Home

ADO.NET 2.0 中的 SqlBulkCopy,C# 中的 SqlBulkCopy 类,SqlBulkCopy 帮助,SqlBulkCopy 指南,SqlBulkCopy 类,SqlBulkCopy 教程

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.39/5 (16投票s)

2007年9月29日

CPOL

4分钟阅读

viewsIcon

97057

ADO.NET 2.0 中的 SqlBulkCopy,C# 中的 SqlBulkCopy 类,SqlBulkCopy 帮助,SqlBulkCopy 指南,使用 SqlBulkCopy 传输数据 - SqlBulkCopy - 在极快的速度下复制 SQL 服务器之间的数据表,使用 .NET 2.0 的 SqlBulkCopy 类执行批量复制,SqlBulkCopy 教程

引言

SqlBulkCopyADO.NET 2.0 中的一项新功能,它能在您需要以编程方式将数据从一个数据库复制到另一个数据库时,提供类似 DTS 的速度。这允许您在源数据存储和目标数据表之间执行大量数据的复制操作。

背景

在我上一个应用程序中,我遇到了一个问题。我必须处理数据迁移。数据是从 FoxPro 迁移到 SQL Server 2005。每个表都有数百万条记录。另一个问题是,有些表包含超过 150 列。FoxPro 数据库中没有规范化的概念,我也必须处理这一点。我偶然发现了 Stem.Data.sqlclient 中的 SqlBulkCopy 类。

这个类极大地帮助我解决了问题。因此,我下定决心与您分享这个类的基本思想。使用传统方法将大量数据从源数据存储复制到 SQL 数据库中的目标表会影响性能,因为您需要多次调用数据库。有一些方法可以解决这个问题,但现在有了 ADO.NET 2.0,您可以执行批量复制并减少数据库访问次数,从而提高性能和速度。SqlBulkCopy 是 ADO.NET 2.0 中批量复制的核心,SqlBulkCopyColumnMappingSqlBulkCopyColumnMappingCollection 对象在此过程中会提供帮助。稍后我将详细讨论这些对象。

Using the Code

SqlBulkCopy

SqlBulkCopy 是帮助您执行批量复制的对象。您可以将 DataReaderDataTable 作为源数据存储(您可以轻松地将数据从 SQL 数据库、Access 数据库、XML 或其他来源加载到这些对象中),并将它们复制到数据库中的目标表。

为了完成这项任务,SqlBulkCopy 使用一个 SqlBulkCopyColumnMapping 对象集合,该集合将作为其 SqlBulkCopyColumnMappingCollection 属性保存。SqlBulkCopyColumnMapping 通过名称或索引将数据源中的列映射到目标表中的表。

SqlBulkCopy 有一些重要的属性,您应该了解它们才能使用它。

  • BatchSize:这个整数值指定每次尝试复制到数据库时应复制的行数。此值直接影响对数据库的访问次数。
  • BulkCopyTimeOut:系统等待 SqlBulkCopy 复制行的时间(秒)。
  • ColumnMappings:一个只读的 SqlBulkCopyColumnMappingCollection。您需要使用其 Add() 方法向其集合中添加新的 SqlBulkCopyColumnMapping 对象。
  • DestinationTableName:目标表名的字符串值。
  • NotifyAfter:当指定的行数已复制后,将调用 SqlRowsCopied 事件处理程序。

此对象还有四个重载。您可以将 SqlConnection(或连接字符串)以及可选的 SqlBulkCopyOptionsSqlTransaction 传递给其构造函数。最后两个参数可以改变 SqlBulkCopy 对象的行为。使用 SqlBulkCopyOptions 枚举,您可以指定例如 SqlBulkCopy 保留标识符或检查约束等其他选项。使用 SqlTransaction,您可以传递一个外部 SqlTransaction,您的 SqlBulkCopy 将在整个过程中使用该事务。

SqlBulkCopy 还有一个 SqlRowsCopied 事件处理程序,当指定数量的 DataRow 被复制后会触发。您通过 NotifyAfter 属性指定了该值。当您想了解处理过程时(例如,通过 ProgressBar 向最终用户显示),此处理程序很有帮助。

有用的方法

关于 SqlBulkCopy 对象最后要提到的是它的 WriteToServer() 方法。这个方法可以接收一个 DataRow 数组、一个 DataTable 或一个 DataReader,并将它们的内容复制到数据库的目标表中。

SqlBulkCopyColumnMapping

SqlBulkCopyColumnMapping 是一个对象,它在批量复制中将源列映射到目标列。SqlBulkCopyColumnMapping 可以通过其属性或构造函数获取源列和目标列的名称或序数。它有这些属性:

  • SourceColumn:源列名的字符串值。
  • SourceOrdinal:源列索引的整数值。
  • DestinationColumn:目标列名的字符串值。
  • DestinationOrdinal:目标列索引的整数值。

应该设置 SourceColumnSourceOrdinal 中的一个,以及 DestinationColumnDestinationOrdinal 中的一个。您也可以通过构造函数设置这些属性,这是一种更简单的方法。

请注意,如果您的源列和目标列名称相同,则不需要使用 SqlBulkCopyColumnMapping 对象,因为 SqlBulkCopy 可以自动完成其工作。

编写一个示例应用程序

让我们看一个例子。我认为您马上会看到的示例应用程序可以涵盖您使用 SqlBulkCopy 所需的所有内容。

注意:如果源和目标两边都有相同的表列,那么我建议您不要指定 SqlBulkCopyColumnMapping 属性,因为它会执行所有任务。

由于两边的列相同,因此使用了 PerformBulkCopy() 方法。

public class mySqlBulkCopy
{
private static void PerformBulkCopy()
{
    string connectionString =
            @"Server=localhost;Database=Northwind;Trusted_Connection=true";
    // get the source data
    using (SqlConnection sourceConnection =
            new SqlConnection(connectionString))
    {
        SqlCommand myCommand =
            new SqlCommand("SELECT * FROM Customer", sourceConnection);
        sourceConnection.Open();
        SqlDataReader reader = myCommand.ExecuteReader();

        // open the destination data
        using (SqlConnection destinationConnection =
                    new SqlConnection(connectionString))
        {
            // open the connection
            destinationConnection.Open();

            using (SqlBulkCopy bulkCopy =
            new SqlBulkCopy(destinationConnection.ConnectionString))
            {
                bulkCopy.BatchSize = 500;
                bulkCopy.NotifyAfter = 1000;
                bulkCopy.SqlRowsCopied +=
                    new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied);
                bulkCopy.DestinationTableName = " Customer_Backup";
                bulkCopy.WriteToServer(reader);
            }
        }
        reader.Close();
    }
}
// this method is used if you want to map columns with different names
// you can also use the index of column by using SourceOrdinal
private static void PerformBulkCopyMyDifferentSchema()
{
    string connectionString = @"Server=
        localhost;Database=Northwind;Trusted_Connection=true";
    DataTable sourceData = new DataTable();
    // get the source data
    using (SqlConnection sourceConnection =
                    new SqlConnection(connectionString))
    {
        SqlCommand myCommand =
            new SqlCommand("SELECT *
            FROM Customer", sourceConnection);
        sourceConnection.Open();
        SqlDataReader reader = myCommand.ExecuteReader();
        // open the destination data
        using (SqlConnection destinationConnection =
                    new SqlConnection(connectionString))
        {
            // open the connection
            destinationConnection.Open();
            using (SqlBulkCopy bulkCopy =
                new SqlBulkCopy(destinationConnection.ConnectionString))
            {
                bulkCopy.ColumnMappings.Add("CustomerID","ID");
                bulkCopy.ColumnMappings.Add("CustomerName", "Name");
                bulkCopy.ColumnMappings.Add("CustomerPoint", "Points");
                bulkCopy.DestinationTableName = " CustomerPoints";
                bulkCopy.WriteToServer(reader);
            }
        }
        reader.Close();
    }
}
}
}

摘要

如果您熟悉 SQLHELPER 类,那么您可以更有效地提高性能。在本文中,我讨论了 ADO.NET 2.0 中新添加的功能 SqlBulkCopy,它帮助您在数据源和数据表之间批量复制大量数据并提高您的性能。

历史

  • 2007 年 9 月 28 日:初次发布
ADO.NET 2.0 中的 SqlBulkCopy,C# 中的 SqlBulkCopy 类,SqlBulkCopy 帮助,SqlBulkCopy 指南,SqlBulkCopy 类,SqlBulkCopy 教程 - CodeProject - 代码之家
© . All rights reserved.