使用asp.net 2.0中的SqlBulkCopy类批量复制数据
介紹:
在軟件開發(fā)中,把數(shù)據(jù)從一個(gè)地方復(fù)制到另一個(gè)地方是一個(gè)普遍的應(yīng)用。 在很多不同的場合都會執(zhí)行這個(gè)操作,包括舊系統(tǒng)到新系統(tǒng)的移植,從不同的數(shù)據(jù)庫備份數(shù)據(jù)和收集數(shù)據(jù)。 ASP.NET 2.0有一個(gè)SqlBulkCopy類,它可以幫助你從不同的數(shù)據(jù)源復(fù)制數(shù)據(jù)到SQL SERVER數(shù)據(jù)庫。 本文中我將示范SqlBulkCopy類的不同應(yīng)用。
數(shù)據(jù)庫設(shè)計(jì):
這個(gè)數(shù)據(jù)庫的設(shè)計(jì)還是蠻簡單的,它基于Northwind數(shù)據(jù)庫的Products表。另外我還在Northwind數(shù)據(jù)庫中創(chuàng)建了3個(gè)表。 詳情可以看一下下面的數(shù)據(jù)庫關(guān)系圖。?
Products_Archive 和Products_Latest有與Products表相同的結(jié)構(gòu),而Products_TopSelling表則與它們不同。 稍后我將在本文解釋Products_TopSelling表的用途。
Products_Archive表包含770,000行。 你不用管這些數(shù)據(jù)是如何得到的,你只需要考慮如何把所有這些數(shù)據(jù)復(fù)制到Products_Latest表里。
從Products_Archive表 復(fù)制數(shù)據(jù)到 Products_Latest表:
SqlBulkCopy 包含一個(gè)方法 WriteToServer,它用來從數(shù)據(jù)的源復(fù)制數(shù)據(jù)到數(shù)據(jù)的目的地。 WriteToServer方法可以處理的數(shù)據(jù)類型有DataRow[]數(shù)組,DataTable 和 DataReader。 你可以根據(jù)不同的情形使用不同的數(shù)據(jù)類型,但是更多時(shí)候選擇DataReader是一個(gè)比較好的主意。 這是因?yàn)镈ataReader是一個(gè)只向前的、只讀的數(shù)據(jù)流,它不會保存數(shù)據(jù),所以要比DataTable 和 DataRows[]都要快。 下面的代碼的作用是把數(shù)據(jù)從源表復(fù)制到目的表。
{
??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();?????????????????
????????????????
??}??????????
}這里有一對需要提及的知識點(diǎn)。 首先,我使用DataReader來從數(shù)據(jù)庫的表中讀取數(shù)據(jù)。 Products_Latest是目的表,因?yàn)閿?shù)據(jù)要從Products_Archive表復(fù)制到Products_Latest表。 bulkCopy對象提供了一個(gè)SqlRowCopied事件,在每次處理完NotifyAfter屬性指定的行數(shù)時(shí)發(fā)生。 本例中的意思就是每處理完1000行就觸發(fā)一次該事件,因?yàn)镹otifyAfter被設(shè)置成了1000
BatchSize屬性是非常重要的,程序性能如何主要就依靠著它。 BatchSize的意思就是同每一批次中的行數(shù),在每一批次結(jié)束時(shí),就將該批次中的行發(fā)送到數(shù)據(jù)庫。 我將BatchSize設(shè)置成了500,其意思就是reader每讀出500行就將他們發(fā)送到數(shù)據(jù)庫從而執(zhí)行批量復(fù)制的操作。 BatchSize的默認(rèn)值是“1”,其意思就是把每一行作為一個(gè)批次發(fā)送到數(shù)據(jù)庫。
設(shè)置不同的BatchSize在性能上將給你帶來不同的結(jié)果。 你應(yīng)該根據(jù)你的需求進(jìn)行測試,來決定BatchSize的大小。
在不同的映射表之間復(fù)制數(shù)據(jù)
在上面的例子中兩個(gè)表具有相同的結(jié)構(gòu)。 有時(shí),你需要在具有不同結(jié)構(gòu)的表之間復(fù)制數(shù)據(jù)。 假如你要從Products_Archive表中把所有的產(chǎn)品名稱及其數(shù)量復(fù)制到Products_TopSelling表里。 這兩個(gè)表有著不同的字段名,具體可以看一下上面的“數(shù)據(jù)庫設(shè)計(jì)”一節(jié)下的。
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文件復(fù)制數(shù)據(jù)到數(shù)據(jù)庫的表中
數(shù)據(jù)源并不局限于數(shù)據(jù)庫的表,你也可以使用XML文件做數(shù)據(jù)源。 這里有一個(gè)非常簡單的使用XML文件做數(shù)據(jù)源進(jìn)行批量復(fù)制操作的例子。
(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文件讀進(jìn)DataTable,然后再使用SqlBulkCopy類的WriteToServer方法。 因?yàn)槟康谋硎臼荘roducts_TopSelling,所以我們必須執(zhí)行列映射。
結(jié)論
本文中我示范了如何使用.NET 2.0引入的SqlBulkCopy類。 SqlBulkCopy類可以非常簡單的把數(shù)據(jù)從一個(gè)數(shù)據(jù)源復(fù)制到SQL SERVER數(shù)據(jù)庫。
我希望你會喜歡本文,祝編程愉快!
轉(zhuǎn)載于:https://www.cnblogs.com/zhoufoxcn/archive/2007/11/07/2515745.html
總結(jié)
以上是生活随笔為你收集整理的使用asp.net 2.0中的SqlBulkCopy类批量复制数据的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 世界杯十六强合影壁纸
- 下一篇: .Net中url传递中文的解决方案