Improve performance using ADO.NET 2.0 batch update feature


Introduction

When you use SqlDataAdapter for performing updates, the SqlDataAdapter propagates the updates one by one. That means if there are 100 rows to be updated the SqlDataAdapter will execute 100 separate operations against the database. As you might have guessed this is not efficient while dealing with large number of rows. Fortunately SqlDataAdapter allows you to execute updates in batches. You can specify the batch size i.e. number of rows to be treated as a single batch via UpdateBatchSize property.

There are also two events associated with this that you can use RowUpdating and RowUpdated. In normal situations i.e. in the absence of batch update, both of these events are raised for each and every row being updated. For example, if we are updating 100 rows, both of these rows are raised for 100 times. However, when you turn on the batch update behavior, the RowUpdating event is raised as in previous case but RowUpdated event is raised after the entire batch is updated. If we set the batch size to 10 then RowUpdating will be raised for 100 times where as RowUpdated will be raised only for 10 times.

Following code illustrates use of this feature:

None.gif class  Program
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif
private static int updating = 0;
InBlock.gif
private static int updated = 0;
InBlock.gif
static void Main(string[] args)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifSqlConnection cnn 
= new SqlConnection(
InBlock.gif
"data source=.\\sqlexpress;
InBlock.gif
initial catalog=northwind;integrated security=true");
InBlock.gif
SqlDataAdapter da = new 
InBlock.gifSqlDataAdapter(
"select * from customers", cnn);
InBlock.gifda.RowUpdating 
+= new 
InBlock.gifSqlRowUpdatingEventHandler(da_RowUpdating);
InBlock.gifda.RowUpdated 
+= new 
InBlock.gifSqlRowUpdatedEventHandler(da_RowUpdated);
InBlock.gifDataSet ds 
= new DataSet();
InBlock.gifda.Fill(ds, 
"mycustomers");
InBlock.gif
foreach (DataRow row in ds.Tables[0].Rows)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gif
string country = row["country"].ToString();
InBlock.gif
//simulate row change
InBlock.gif
row["country"= country;
ExpandedSubBlockEnd.gif}

InBlock.gifSqlCommand cmd 
= new SqlCommand();
InBlock.gifcmd.Connection 
= cnn;
InBlock.gifcmd.CommandType 
= CommandType.Text;
InBlock.gifcmd.CommandText 
= "update customers set 
InBlock.gif
country=@country where customerid=@custid";
InBlock.gif
SqlParameter p1 = new 
InBlock.gifSqlParameter(
"@country", SqlDbType.VarChar);
InBlock.gifp1.SourceColumn 
= "country";
InBlock.gifSqlParameter p2 
= new 
InBlock.gifSqlParameter(
"@custid", SqlDbType.VarChar);
InBlock.gifp2.SourceColumn 
= "customerid";
InBlock.gifcmd.Parameters.Insert(
0, p1);
InBlock.gifcmd.Parameters.Insert(
0, p2);
InBlock.gifcmd.UpdatedRowSource 
= UpdateRowSource.None;
InBlock.gifda.UpdateCommand 
= cmd;
InBlock.gifda.UpdateBatchSize 
= 10;
InBlock.gifda.Update(ds, 
"mycustomers");
InBlock.gifConsole.WriteLine(
"Updating :" + updating);
InBlock.gifConsole.WriteLine(
"Updated :" + updated);
InBlock.gifConsole.ReadLine();
ExpandedSubBlockEnd.gif}

InBlock.gif
static void da_RowUpdating
InBlock.gif(
object sender, SqlRowUpdatingEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifupdating
++;
ExpandedSubBlockEnd.gif}

InBlock.gif
static void da_RowUpdated
InBlock.gif(
object sender, SqlRowUpdatedEventArgs e)
ExpandedSubBlockStart.gifContractedSubBlock.gif
dot.gif{
InBlock.gifupdated
++;
ExpandedSubBlockEnd.gif}

ExpandedBlockEnd.gif}

Notice how we have attached event handlers to the RowUpdating and RowUpdated events. These event handlers simply increment two integer variables. Then we set the UpdatedDataSource property of the SqlCommand property to enumerated value of UpdateRowSource.None. The UpdatedRowSource property can control how the values returned from the data source are mapped back to the DataSet. Setting this property to a value of None is necessary when using batch update feature of DataAdapter. Finally, we set the UpdateBatchSize property of the SqlDataAdapter to 10 indicating that we want to update 10 rows as a batch. If you run this application you will notice that the variable updating holds the value equal to the number of rows in the table because this event is raised each time a row is being updated. On the other hand the variable update will hold value equal to (number of rows in the table) / (batch size).

Summary

In ADO.NET 2.0, the DataAdapter provides a property called UpdateBatchSize which allows you to execute queries in a batch. This significantly reduces the database roundtrips and hence is more efficient in terms of performance

  转自
http://www.dotnetbips.com/articles/displayarticle.aspx?id=487





转载于:https://www.cnblogs.com/gwazy/archive/2005/12/30/307924.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值