1. 程式人生 > >使用 DataAdapter 執行批量更新

使用 DataAdapter 執行批量更新

【理論基礎】

      在2.0以前版本的 ADO.NET 中,使用 DataSet 中的更改來更新資料庫時,DataAdapter 的 Update 方法每次更新資料庫的一行。因為該方法迴圈訪問指定 DataTable 中的行,所以,會檢查每個 DataRow,確定是否已修改。如果該行已修改,將根據該行的 RowState 屬性值呼叫相應的 UpdateCommand、InsertCommand 或 DeleteCommand。每一次行更新都涉及網路與資料庫之間的雙向資料傳輸。

      ——注意這段話的意思是根據DataSet中每一行的RowState值,採取相應的資料操作:由DataAdapter 呼叫相應的命令執行。在ADO.NET 2.0版本中也是這樣執行的。

      在 ADO.NET 2.0 中,DataAdapter 公開了 UpdateBatchSize 屬性。將 UpdateBatchSize 設定為正整數值將使對資料庫的更新以指定大小的批次進行傳送。例如,如果將 UpdateBatchSize 設定為 10,會將 10 個獨立的語句組合在一起並作為一批提交。將 UpdateBatchSize 設定為 0 將導致 DataAdapter 使用伺服器可以處理的最大批次的大小。如果將其設定為 1,則禁用批量更新,因為此時每次傳送一行。

      ——UpdateBatchSize 屬性是實現批量修改資料的關鍵。

【具體實現】

這是一個進行批量修改的函式,引數為一個dataTable和批次大小的值batchSize。為簡單起見這裡僅對修改的資料進行更新。

        public static void BatchUpdate(DataTable dataTable, Int32 batchSize)
        {
           // Assumes GetConnectionString() returns a valid connection string.
            string connectionString = GetConnectionString();

            // Connect to the AdventureWorks database.
            using (SqlConnection connection = new
              SqlConnection(connectionString))
            {

                // Create a SqlDataAdapter.
                SqlDataAdapter adapter = new SqlDataAdapter();

                // Set the UPDATE command and parameters.
                adapter.UpdateCommand = new SqlCommand(
                    "UPDATE Table_Student SET "
                    + "[email protected] WHERE [email protected];",
                    connection);
                adapter.UpdateCommand.Parameters.Add("@StudentName",
                   SqlDbType.NVarChar, 50, "StudentName");
                adapter.UpdateCommand.Parameters.Add("@StudentID",
                   SqlDbType.Int, 4, "StuID");
                adapter.UpdateCommand.UpdatedRowSource = UpdateRowSource.None;

                adapter.UpdateBatchSize = batchSize;

                // Execute the update.
                adapter.Update(dataTable);
            }
        }

以下是對該方法的呼叫,寫在Main函式中。

        static void Main(string[] args)
        {
            DataTable dt = new DataTable();

            dt.Columns.Add("StuID", typeof(string));
            dt.Columns.Add("StudentName", typeof(string));                       

            DataRow dr = dt.NewRow();

            dt.Rows.Add(dr);

            dt.AcceptChanges();

            dt.Rows[0][0] = "1002";
            dt.Rows[0][1] = "***";

            BatchUpdate(dt, 10);

        }

在該函式中注意各語句的執行順序,因為執行順序不同DataRow的RowState值是不一樣的。尤其適當迴圈改變資料時。

另外注意:兩處為褐色的StuID,這說明,adapter.UpdateCommand.Parameters.Add方法中的第四個引數源資料值得是dataTable中對應列的值。

下面附上行狀態的說明。

每個 DataRow 物件都具有 RowState 屬性,您可以檢查此屬性來確定行的當前狀態。下表提供了對每個 RowState 列舉值的簡短說明。

RowState

說明

自上次呼叫 AcceptChanges 以來或由 DataAdapter.Fill 建立該行以來,沒有進行任何更改。

Added

已將該行新增到表中,但尚未呼叫 AcceptChanges。

已從表中刪除該行,並且尚未呼叫 AcceptChanges。

該行不是任何 DataRowCollection 的一部分。新建立的行的 RowState 設定為 Detached。通過呼叫Add 方法將新的 DataRow 新增到 DataRowCollection 後,RowState 屬性的值設定為 Added。

將使用 Remove 方法,或使用 Delete 方法接著使用 AcceptChanges 方法從 DataRowCollection 中移除的行也設定為 Detached。

 DataSetDataTable 或 DataRow 呼叫 AcceptChanges 時,會移除行狀態為 Deleted 的所有行。剩餘行的行狀態為Unchanged,並且 Original 行版本中的值將被 Current 行版本值覆蓋。呼叫 RejectChanges 時,會移除行狀態為 Added 的所有行。剩餘行的行狀態為 Unchanged,並且 Current 行版本中的值將被 Original 行版本值覆蓋。