zoukankan      html  css  js  c++  java
  • [转载][翻译]使用asp.net 2.0中的SqlBulkCopy类批量复制数据


    摘要:
            突然发现在C#2.0中为数据的导入提供了一个这么好的类,自己一直都没发现,昨天在找资料的时候刚好到了codeproject,并看到了现在这篇文章,于是便爱好上了,觉得写得很不错,拿出来和大家分享分享,但是这篇中文版的却不是我翻译的,我在另外在资料的时候看到另外一个同胞竟然把它翻译过来了,看得我是大为感动啊,要是还不拿出来一起分享,就太对不起大家了。呵呵,本人正在做各种格式数据导出和导入,数据量很大,很希望能够在完成基本任务的同时能大大地提高工作效率,对此有感受或者有经验的同志们还请多多指点,谢谢!




    原文地址:http://gridviewguy.com/ArticleDetails.aspx?articleID=233
    [原文源码下载]

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


    原文发布日期:2007.03.01
    作者:AzamSharp
    翻译:webabcd


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

    我希望你会喜欢本文,祝编程愉快!

  • 相关阅读:
    1014 Waiting in Line (30)(30 point(s))
    1013 Battle Over Cities (25)(25 point(s))
    1012 The Best Rank (25)(25 point(s))
    1011 World Cup Betting (20)(20 point(s))
    1010 Radix (25)(25 point(s))
    1009 Product of Polynomials (25)(25 point(s))
    1008 Elevator (20)(20 point(s))
    1007 Maximum Subsequence Sum (25)(25 point(s))
    1006 Sign In and Sign Out (25)(25 point(s))
    1005 Spell It Right (20)(20 point(s))
  • 原文地址:https://www.cnblogs.com/hanchan/p/885162.html
Copyright © 2011-2022 走看看