在ASP.NET 2.0中提供了一个新的类SqlBulkCopy类,它在性能上的优势更超过了上面的方法,它可以通过让DataSet或是DataReader中大量的数据通过数据流直接进行装载,然后可以将这些记录添加到指定的数据表中。
SqlBulkCopy类只有在SQL Server的表中写入数据,但在使用其它的数据库时,可以通过数据源来使用,SqlBulkCopy类主要包括一个实例方法WriteToServer,它用来把数据从一个数据源传输到另外一个数据源。WriteToServer的方法可以快速的写入DataRow数组数据,DataTable和DataReader。在实际开发的过程中,可以视情况而定,选择我们所喜欢的方法,我们看它使用的方法: WriteToServer(DataTable)写入数据表 WriteToServer(DataRow)批次写入数据行 WriteToServer(DataTable,DataRowState)按行状态写入数据库表 WriteToServer(DataReader)写入DataReader对象 在多数情况下,我们选择最好的方法是DataReader对象,因为DataReader是一个读取只向前和只读流的方式,所以它要比DataTable和DataRows更快,我们现在来看看下面的代码,它用来把数据从一张表中传输到另一张表中。 代码清单: string strConnection = ConfigurationManager.AppSettings["conStr"].ToString();//读取Web.config文件中的数据库连接字符串 SqlConnection sourceconnection = new SqlConnection(strConnection);//数据的连接方式是SQL Server sourceconnection.Open();//打开数据库连接 SqlCommand cmd = new SqlCommand("Select * from MSreplication_options");//通过命令来读取SQL语句 cmd.Connection = sourceconnection;//获取连接方式 SqlDataReader reader = cmd.ExecuteReader();//开始执和结果集,获取DataReader记录集 //连接目标数据库连接,并且打开数据库连接方式,在此由于调用同一个数据库,连接字符串没有变 SqlConnection destinationConnection = new SqlConnection(strConnection); destinationConnection.Open(); //调用SqlBulkCopy类的方法 SqlBulkCopy bulkCopy = new SqlBulkCopy(destinationConnection); //获取目标表的名称 bulkCopy.DestinationTableName = "destination"; //写入DataReader对象 bulkCopy.WriteToServer(reader); //关闭各个对象 reader.Close(); sourceconnection.Close(); destinationConnection.Close(); 上例中,我们使用的是SQL Server 2005的master数据库,我们在使用SqlBulkCopy的时候,需要了解一下它的几个重要的属性: BatchSize:属性的整数值;或者如果未设置任何值,则为零。每一批次中的行数。在每一批次结束时,将该批次中的行发送到服务器。 BulkCopyTimeOu:超时之前操作完成所允许的秒数。如果操作超时,事务便不会提交,而且所有已复制的行都会从目标表中移除。 ColumnMappings:返回 SqlBulkCopyColumnMapping 项的集合。列映射定义数据源中的列和目标表中的列之间的关系。如果数据源和目标表具有相同的列数,并且数据源中每个源列的序号位置匹配相应目标列的序号位置,则无需 ColumnMappings 集合。但是如果列计数不同,或序号位置不一致,则必须使用 ColumnMappings,以确保将数据复制到正确的列中。 DestinationTableName:指定的目标表中。 NotifyAfter:属性的整数值,或者如果未设置该属性,则为零。定义在生成通知事件之前要处理的行数。 在ColumnMappings属性中,我们可以看到SqlBulkCopyColumnMapping 项,它主要是用来定义SqlBulkCopy实例的数据源中的列与该实例的目标表中的列之间的映射。 结合着上面SqlBulkCopy的属性我们再来看一个综合的例子,此例中我们使用DataTable: 在本例中,我先自己建立一个数据库SqlBulkCopySample,然后建立一个表TblOrder,它主要是用来把Northwind数据库中的Orders表数据全导进来,所以它的表结构基本上和Orders一样,它们以应的关系如下: ID (OrderID): int Name (ShipName): nvarchar(40) Address (ShipAddress): nvarchar(60) City (ShipCity): nvarchar(15) 然后在Northwind数据中创建一个存储过程,如下: CREATE PROCEDURE dbo.SelectOrders AS SELECT OrderID, ShipName, ShipAddress, ShipCity FROM Orders 我们在页面中增加一个按钮的点击事件,当事件触发的时候,执行的代码如下: private void btnStart_Click(object sender, EventArgs e) { String sourceConnectionString ="Data Source=127.0.0.1;Initial Catalog=Northwind;Integrated Security=True"; String destinationConnectionString ="Data Source=127.0.0.1;;Initial Catalog=SqlBulkCopySample;Integrated Security=True"; DataTable data = SelectDataFromSource(sourceConnectionString);//获取数据 CopyDataToDestination(destinationConnectionString, data);//复制数据 } 获取数据非常简单,它只是通过执行存储过程返回一个DataTable的查询结果集,如下: private DataTable SelectDataFromSource(String connectionString) { DataTable data = new DataTable(); using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand command = new SqlCommand("SelectOrders", connection); command.CommandType = CommandType.StoredProcedure; connection.Open(); SqlDataReader reader = command.ExecuteReader(); data.Load(reader); } return data; } 接着,就执行数据复制的操作,此部分的代码为核心的部分,首先我们通过创建四个SqlBulkCopyColumnMapping对象,然后把两个数据库中的表之间的一一对应关系表述出来,然后设置好BatchSize及BulkCopyTimeout属性,然后返回 SqlBulkCopyColumnMapping 项的集合,接着定义好目标表的名称,以SqlRowsCopied事件处理程序,在定义在生成通知事件之前要处理的行数时,然后调用WriteToServer(DataTable) 方法写入数据表,结束数据的复制,如下: private void CopyDataToDestination(String connectionString, DataTable table) { //如果表结构一样则可以省略SqlBulkCopyColumnMapping
SqlBulkCopyColumnMapping mapping1 =new SqlBulkCopyColumnMapping("OrderID", "ID"); SqlBulkCopyColumnMapping mapping2 =new SqlBulkCopyColumnMapping("ShipName", "Name"); SqlBulkCopyColumnMapping mapping3 =new SqlBulkCopyColumnMapping("ShipAddress", "Address"); SqlBulkCopyColumnMapping mapping4 =new SqlBulkCopyColumnMapping("ShipCity", "City"); SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString); bulkCopy.BatchSize = 100; bulkCopy.BulkCopyTimeout = 5; bulkCopy.ColumnMappings.Add(mapping1); bulkCopy.ColumnMappings.Add(mapping2); bulkCopy.ColumnMappings.Add(mapping3); bulkCopy.ColumnMappings.Add(mapping4); bulkCopy.DestinationTableName = "tblOrder"; bulkCopy.SqlRowsCopied +=new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied); bulkCopy.NotifyAfter = 200; bulkCopy.WriteToServer(table); } 在bulkCopy_SqlRowsCopied的处理中,我只简单的通过展现给用户一个友好的提示信息让你可以知道目前有多少行被复制成功。代码如下: private void bulkCopy_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e) { MessageBox.Show(String.Format("{0} Rows have been copied.", e.RowsCopied.ToString())); } 这样,在平时的开发中,我们可以灵活的在ASP.NET中使用SqlBulkCopy帮助我们复制大量的数据之间的数据源和数据表,并改善应用程序的性能。 获取数据非常简单,它只是通过执行存储过程返回一个DataTable的查询结果集,如下: private DataTable SelectDataFromSource(String connectionString) { DataTable data = new DataTable(); using (SqlConnection connection = new SqlConnection(connectionString)) { SqlCommand command = new SqlCommand("SelectOrders", connection); command.CommandType = CommandType.StoredProcedure; connection.Open(); SqlDataReader reader = command.ExecuteReader(); data.Load(reader); } return data; } 接着,就执行数据复制的操作,此部分的代码为核心的部分,首先我们通过创建四个SqlBulkCopyColumnMapping对象,然后把两个数据库中的表之间的一一对应关系表述出来, 然后设置好BatchSize及BulkCopyTimeout属性,然后返回 SqlBulkCopyColumnMapping 项的集合,接着定义好目标表的名称,以SqlRowsCopied事件处理程序,在定义在生成通知事件之前要处理的行数时,然后调用WriteToServer(DataTable) 方法写入数据表,结束数据的复制,如下: private void CopyDataToDestination(String connectionString, DataTable table) { SqlBulkCopyColumnMapping mapping1 =new SqlBulkCopyColumnMapping("OrderID", "ID"); SqlBulkCopyColumnMapping mapping2 =new SqlBulkCopyColumnMapping("ShipName", "Name"); SqlBulkCopyColumnMapping mapping3 =new SqlBulkCopyColumnMapping("ShipAddress", "Address"); SqlBulkCopyColumnMapping mapping4 =new SqlBulkCopyColumnMapping("ShipCity", "City"); SqlBulkCopy bulkCopy = new SqlBulkCopy(connectionString); bulkCopy.BatchSize = 100; bulkCopy.BulkCopyTimeout = 5; bulkCopy.ColumnMappings.Add(mapping1); bulkCopy.ColumnMappings.Add(mapping2); bulkCopy.ColumnMappings.Add(mapping3); bulkCopy.ColumnMappings.Add(mapping4); bulkCopy.DestinationTableName = "tblOrder"; bulkCopy.SqlRowsCopied +=new SqlRowsCopiedEventHandler(bulkCopy_SqlRowsCopied); bulkCopy.NotifyAfter = 200; bulkCopy.WriteToServer(table); } 在bulkCopy_SqlRowsCopied的处理中,我只简单的通过展现给用户一个友好的提示信息让你可以知道目前有多少行被复制成功。代码如下: private void bulkCopy_SqlRowsCopied(object sender, SqlRowsCopiedEventArgs e) { MessageBox.Show(String.Format("{0} Rows have been copied.", e.RowsCopied.ToString())); } 这样,在平时的开发中,我们可以灵活的在ASP.NET中使用SqlBulkCopy帮助我们复制大量的数据之间的数据源和数据表,并改善应用程序的性能。 |