博客园  :: 首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理

使用 DataAdapter 执行批量更新

Posted on 2010-11-11 20:38  itcfj  阅读(2032)  评论(0编辑  收藏  举报

使用 DataAdapter 执行批量更新

2006-04-29 22:06 by Clingingboy, 1461 visits, 网摘,收藏,编辑

   摘自MSDN:

在以前版本的 ADO.NET 中,使用 DataSet 中的更改来更新数据库时,DataAdapter 的 Update 方法每次更新数据库的一行。因为该方法循环访问指定 DataTable 中的行,所以,会检查每个 DataRow,确定是否已修改。如果该行已修改,将根据该行的 RowState 属性值调用相应的 UpdateCommand、InsertCommand 或 DeleteCommand。每一次行更新都涉及网络与数据库之间的双向数据传输。

在ADO.NET 2.0 中,DataAdapter 公开了UpdateBatchSize 属性。将 UpdateBatchSize 设置为正整数值将使对数据库的更新以指定大小的批次进行发送。例如,如果将 UpdateBatchSize 设置为 10,会将 10 个独立的语句组合在一起并作为一批提交。将 UpdateBatchSize 设置为 0 将导致 DataAdapter 使用服务器可以处理的最大批次的大小。如果将其设置为 1,则禁用批量更新,因为此时每次发送一行。

执行非常大的批次可能会降低性能。因此,在实现应用程序之前,应测试最佳的批次大小设置。

使用 UpdateBatchSize 属性

启用了批量更新后,DataAdapter 的 UpdateCommand、InsertCommand 和 DeleteCommand 的 UpdatedRowSource 属性值应设置为 None 或 OutputParameters。在执行批量更新时,命令的FirstReturnedRecord 或 Both 的UpdatedRowSource 属性值无效。

下面的过程演示如何使用 UpdateBatchSize 属性。该过程采用两个参数,一个 DataSet 对象,其中包含代表 Production.ProductCategory 表中的ProductCategoryID 和 Name 字段的列,一个代表批次大小的整数(批次中的行数)。该代码创建一个新的 SqlDataAdapter 对象,设置其 UpdateCommand、InsertCommand 和 DeleteCommand 属性。该代码假定 DataSet 对象已修改了行。它设置 UpdateBatchSize 属性并执行更新。

protected void btnUpdateAddress_Click(object sender, EventArgs e)
    {
        SqlDataAdapter EmpAdapter = new SqlDataAdapter();
        DataTable EmpDT = new DataTable();
        SqlConnection DBConSelect = new SqlConnection();
        SqlConnection DBConUpdate = new SqlConnection();
        SqlCommand SelectCommand = new SqlCommand();
        SqlCommand UpdateCommand = new SqlCommand();

        // Using different connection objects for select and updates from the 
        // Northwind database. 
        DBConSelect.ConnectionString = 
          ConfigurationManager.ConnectionStrings["DSN_NorthWind"].ConnectionString;
        DBConUpdate.ConnectionString = 
          ConfigurationManager.ConnectionStrings["DSN_NorthWind"].ConnectionString;

        // Reading all records from the Employees table
        SelectCommand.CommandText = "SELECT top 500 * FROM EMPLOYEES";
        SelectCommand.CommandType = CommandType.Text;
        SelectCommand.Connection = DBConSelect;

        UpdateCommand.CommandText = " UPDATE EMPLOYEES SET Address=@Address, " + 
                                    "City=@City, Region=@Region, Country=@Country";

        UpdateCommand.CommandType = CommandType.Text;
        UpdateCommand.Connection = DBConUpdate;

        SqlParameter AddressParam;
        AddressParam = new SqlParameter("@Address", 
           SqlDbType.VarChar, 15, "Address");

        SqlParameter CityParam;
        CityParam = new SqlParameter("@City", SqlDbType.VarChar, 15, "City");

        SqlParameter RegionParam;
        RegionParam = new SqlParameter("@Region", SqlDbType.VarChar, 15, "Region");

        SqlParameter CountryParam;
        CountryParam = new SqlParameter("@Country", 
           SqlDbType.VarChar, 15, "Country");

        UpdateCommand.Parameters.Add(AddressParam);
        UpdateCommand.Parameters.Add(CityParam);
        UpdateCommand.Parameters.Add(RegionParam);
        UpdateCommand.Parameters.Add(CountryParam);

        // Setting up Data Adapter with the Select and Update Commands
        // The Select command will be used to retrieve all employee
        // information from the Northwind database and the Update command
        // will be used to save changes back to the database
        EmpAdapter.SelectCommand = SelectCommand;
        EmpAdapter.UpdateCommand = UpdateCommand;

        EmpAdapter.Fill(EmpDT);

        DBConSelect.Close();

        // Looping through all employee records and assigning them the new 
        // address
        foreach (DataRow DR in EmpDT.Rows)
        {
            DR["Address"] = "4445 W 77th Street, Suite 140";
            DR["City"] = "Edina";
            DR["Region"] = "Minnesota";
            DR["Country"] = "USA";
        }

        // Adding an event handler to listen to the RowUpdated event.
        // This event will will fire after each batch is executed
        EmpAdapter.RowUpdated +=  new SqlRowUpdatedEventHandler(OnRowUpdated);

        lblCounter.Text = "";

        EmpAdapter.UpdateBatchSize = 100;

        // It is important to set this property for batch processing of 
        // updated records since batch updates are incapable of 
        // updating the source with changes from the database
        UpdateCommand.UpdatedRowSource = UpdateRowSource.None;

        try
        {
            DBConUpdate.Open();
            EmpAdapter.Update(EmpDT);
        }
        catch (Exception ex)
        {
            lblCounter.Text += ex.Message + "<Br>";
        }
        finally
        {
            if (DBConUpdate.State == ConnectionState.Open)
            {
                DBConUpdate.Close();
            }
        }
    }

    private void OnRowUpdated(object sender, SqlRowUpdatedEventArgs args)
    {
        lblCounter.Text += "Batch is processed till row number = " + 
           args.RowCount.ToString() + "<br>";
    }

 

 

[转]使用DataAdapter 执行批量更新

使用 DataAdapter 执行批量更新

在以前版本的 ADO.NET 中,使用 DataSet 中的更改来更新数据库时,DataAdapter的 Update 方法每次更新数据库的一行。因为该方法循环访问指定 DataTable 中的行,所以,会检查每个 DataRow,确定是否已修改。如果该行已修改,将根据该行的 RowState 属性值调用相应的UpdateCommand、InsertCommand 或DeleteCommand。每一次行更新都涉及网络与数据库之间的双向数据传输。

在ADO.NET 2.0 中,DataAdapter 公开了 UpdateBatchSize 属性。将UpdateBatchSize 设置为正整数值将使对数据库的更新以指定大小的批次进行发送。例如,如果将UpdateBatchSize 设置为 10,会将 10 个独立的语句组合在一起并作为一批提交。将 UpdateBatchSize 设置为 0 将导致 DataAdapter 使用服务器可以处理的最大批次的大小。如果将其设置为 1,则禁用批量更新,因为此时每次发送一行。

执行非常大的批次可能会降低性能。因此,在实现应用程序之前,应测试最佳的批次大小设置。

使用 UpdateBatchSize 属性

启用了批量更新后,DataAdapter 的 UpdateCommand、InsertCommand 和 DeleteCommand 的 UpdatedRowSource 属性值应设置为 NoneOutputParameters。在执行批量更新时,命令的 FirstReturnedRecordBoth 的UpdatedRowSource 属性值无效。

下面的过程演示如何使用 UpdateBatchSize 属性。该过程采用两个参数,一个 DataSet 对象,其中包含代表Production.ProductCategory 表中的 ProductCategoryID 和 Name 字段的列,一个代表批次大小的整数(批次中的行数)。该代码创建一个新的 SqlDataAdapter 对象,设置其 UpdateCommandInsertCommandDeleteCommand 属性。该代码假定DataSet 对象已修改了行。它设置 UpdateBatchSize 属性并执行更新。

Visual Basic

 

复制代码

Public Sub BatchUpdate( _

 ByVal dataTable AsDataTable, ByVal batchSize As Int32)

    ' Assumes GetConnectionString()returns a valid connection string.

    DimconnectionString As String= GetConnectionString()

 

    ' Connect to theAdventureWorks database.

    Using connection AsNew SqlConnection(connectionString)

        ' Create aSqlDataAdapter.

        Dim adapter As New SqlDataAdapter()

 

        'Set theUPDATE command and parameters.

        adapter.UpdateCommand = New SqlCommand( _

          "UPDATEProduction.ProductCategory SET " _

          & "Name=@NameWHERE ProductCategoryID=@ProdCatID;", _

          connection)

        adapter.UpdateCommand.Parameters.Add("@Name", _

          SqlDbType.NVarChar, 50, "Name")

        adapter.UpdateCommand.Parameters.Add("@ProdCatID",  _

          SqlDbType.Int, 4, " ProductCategoryID ")

        adapter.UpdateCommand.UpdatedRowSource= _

          UpdateRowSource.None

 

        'Set theINSERT command and parameter.

        adapter.InsertCommand = New SqlCommand( _

          "INSERTINTO Production.ProductCategory (Name) VALUES (@Name);", _

 connection)

        adapter.InsertCommand.Parameters.Add("@Name", _

          SqlDbType.NVarChar, 50, "Name")

        adapter.InsertCommand.UpdatedRowSource= _

          UpdateRowSource.None

 

        'Set theDELETE command and parameter.

        adapter.DeleteCommand = New SqlCommand( _

          "DELETEFROM Production.ProductCategory " _

          & "WHEREProductCategoryID=@ProdCatID;", connection)

        adapter.DeleteCommand.Parameters.Add("@ProdCatID", _

           SqlDbType.Int, 4, " ProductCategoryID ")

        adapter.DeleteCommand.UpdatedRowSource= UpdateRowSource.None

 

        ' Set thebatch size.

        adapter.UpdateBatchSize = batchSize

 

        ' Execute theupdate.

        adapter.Update(dataTable)

    End Using

End Sub

C#

 

复制代码

public static void BatchUpdate(DataTable dataTable,Int32 batchSize)

{

    // AssumesGetConnectionString() returns a valid connection string.

    stringconnectionString = GetConnectionString();

 

    // Connect to theAdventureWorks database.

    using(SqlConnection connection = new

      SqlConnection(connectionString))

    {

 

        // Create aSqlDataAdapter.

        SqlDataAdapter adapter = new SqlDataAdapter();

 

        // Set theUPDATE command and parameters.

        adapter.UpdateCommand = new SqlCommand(

            "UPDATEProduction.ProductCategory SET "

            + "Name=@NameWHERE ProductCategoryID=@ProdCatID;",

            connection);

        adapter.UpdateCommand.Parameters.Add("@Name",

           SqlDbType.NVarChar, 50, "Name");

        adapter.UpdateCommand.Parameters.Add("@ProdCatID",

           SqlDbType.Int, 4, "ProductCategoryID");

         adapter.UpdateCommand.UpdatedRowSource= UpdateRowSource.None;

 

        // Set theINSERT command and parameter.

        adapter.InsertCommand = new SqlCommand(

            "INSERTINTO Production.ProductCategory (Name) VALUES (@Name);",

            connection);

        adapter.InsertCommand.Parameters.Add("@Name",

          SqlDbType.NVarChar, 50, "Name");

        adapter.InsertCommand.UpdatedRowSource= UpdateRowSource.None;

 

        // Set theDELETE command and parameter.

        adapter.DeleteCommand = new SqlCommand(

            "DELETEFROM Production.ProductCategory "

            + "WHEREProductCategoryID=@ProdCatID;", connection);

        adapter.DeleteCommand.Parameters.Add("@ProdCatID",

          SqlDbType.Int, 4, "ProductCategoryID");

        adapter.DeleteCommand.UpdatedRowSource= UpdateRowSource.None;

 

        // Set thebatch size.

        adapter.UpdateBatchSize = batchSize;

 

        // Executethe update.

        adapter.Update(dataTable);

    }

}