介紹:
在軟件開發中,把數據從一個地方複製到另一個地方是一個普遍的應用。 在很多不同的場合都會執行這個操作,包括舊系統到新系統的移植,從不同的數據庫備份數據和收集數據。 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[]都要快。 下面的代碼的作用是把數據從源表複製到目的表。
{
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();
}
}
BatchSize屬性是非常重要 的,程序性能如何主要就依靠着它。 BatchSize的意思就是同每一批次中的行數,在每一批次結束時,就將該批次中的行發送到數據庫。 我將BatchSize設置成了500,其意思就是reader每讀出500行就將他們發送到數據庫從而執行批量複製的操作。 BatchSize的默認值是“1”,其意思就是把每一行作爲一個批次發送到數據庫。
設置不同的BatchSize在性能上將給你帶來不同的結果。 你應該根據你的需求進行測試,來決定BatchSize的大小。
在不同的映射表之間複製數據
在 上面的例子中兩個表具有相同的結構。 有時,你需要在具有不同結構的表之間複製數據。 假如你要從Products_Archive表中把所有的產品名稱及其數量複製到Products_TopSelling表裏。 這兩個表有着不同的字段名,具體可以看一下上面的“數據庫設計”一節下的。
{
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();
}
}
從XML文件複製數據到數據庫的表中
數據源並不侷限於數據庫的表,你也可以使用XML文件做數據源。 這裏有一個非常簡單的使用XML文件做數據源進行批量複製操作的例子。
(Products.xml)
<Products>
<Product productID="1" productName="Chai" />
<Product productID="2" productName="Football" />
<Product productID="3" productName="Soap" />
<Product productID="4" productName="Green Tea" />
</Products>
{
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);
}
}
}
結論
本文中我示範瞭如何使用.NET 2.0引入的SqlBulkCopy類。 SqlBulkCopy類可以非常簡單的把數據從一個數據源複製到SQL SERVER數據庫。
我希望你會喜歡本文,祝編程愉快!