使用 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 建立該行以來,沒有進行任何更改。 |
|
已將該行新增到表中,但尚未呼叫 AcceptChanges。 |
|
已從表中刪除該行,並且尚未呼叫 AcceptChanges。 |
|
該行不是任何 DataRowCollection 的一部分。新建立的行的 RowState 設定為 Detached。通過呼叫Add 方法將新的 DataRow 新增到 DataRowCollection 後,RowState 屬性的值設定為 Added。 將使用 Remove 方法,或使用 Delete 方法接著使用 AcceptChanges 方法從 DataRowCollection 中移除的行也設定為 Detached。 |
對 DataSet、DataTable 或 DataRow 呼叫 AcceptChanges 時,會移除行狀態為 Deleted 的所有行。剩餘行的行狀態為Unchanged,並且 Original 行版本中的值將被 Current 行版本值覆蓋。呼叫 RejectChanges 時,會移除行狀態為 Added 的所有行。剩餘行的行狀態為 Unchanged,並且 Current 行版本中的值將被 Original 行版本值覆蓋。