使用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數據庫。數據庫

相關文章
相關標籤/搜索