程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> C#入門知識 >> C#利用SqlDataAdapte對DataTable進行批量數據操作,

C#利用SqlDataAdapte對DataTable進行批量數據操作,

編輯:C#入門知識

C#利用SqlDataAdapte對DataTable進行批量數據操作,


  C#利用SqlDataAdapte對DataTable進行批量數據操作,可以讓我們大大簡化操作數據的代碼量,我們幾乎不需要循環和不關心用戶到底是新增還是修改,更不用編寫新增和修改以及刪除的SQL語句,適配器都幫我們在後台進行了很好的處理.

  如果您要通過 SQL Server 存儲過程使用 DataAdapter 來編輯或刪除數據,請確保不要在存儲過程定義中使用 SET NOCOUNT ON。這將使返回的受影響的行數為零,DataAdapter 會將其解釋為並發沖突。在許多情況下,以何種順序向數據源發送通過 DataSet 所做的更改是非常重要的。例如,如果更新了現有行的主鍵值,並且添加了以新主鍵值作為外鍵的新行,則務必要在處理插入之前處理更新。可以使用 DataTable 的 Select 方法來返回僅引用具有特定 RowState 的 DataRow 數組。然後可以將返回的 DataRow 數組傳遞給 DataAdapter 的 Update 方法來處理已修改的行。通過指定要更新的行的子集,可以控制處理插入、更新和刪除的順序。以下代碼確保首先處理表中已刪除的行,然後處理已更新的行,然後處理已插入的行。

1 DataTable table = dataSet.Tables["Customers"];
2 //第一步處理刪除.
3 adapter.Update(table.Select(null, null, DataViewRowState.Deleted));
4 //接著處理更新
5 adapter.Update(table.Select(null, null, 
6   DataViewRowState.ModifiedCurrent));
7 //最後處理新增
8 adapter.Update(table.Select(null, null, DataViewRowState.Added));

 注意   對 DataSet、DataTable 或 DataRow 調用 AcceptChanges 將導致 DataRow 的所有 Original 值被 DataRow 的 Current 值覆蓋。如果修改了唯一標識該行的字段值,則在調用 AcceptChanges 後,Original 值將不再匹配數據源中的值。在調用 DataAdapter 的 Update 方法期間會對每一行自動調用 AcceptChanges。在調用 Update 方法期間,通過先將 DataAdapter 的 AcceptChangesDuringUpdate 屬性設置為 false,或為 RowUpdated 事件創建一個事件處理程序並將 Status 設置為 SkipCurrentRow,可以保留原始值。(來自MSDN) 

1 強類型數據集

  數據庫的表設計好後,可以用VS連接數據庫,並將myUser 表拖放到數據集設計器中(重命名為dsUser),默認情況下,數據集會自動生成Fill方法,我們這裡需要手動進行刪除,只保留表結構即可,數據查詢和操作邏輯我們進行自定義.如下圖所示:

2 UI設計

  新建一個窗體,編譯後可以從工具欄將上一步新建的dsUser強類型數據集拖放到窗體上,另外添加一個BindingSource控件(主要用於對DataGridView中的數據庫和DataSet的數據進行綁定)

  BindingSource中選擇數據源DataSource為dsUser,然後選擇數據集中的一個表myUser進行綁定:

  設置DataGridView的數據源為bindingSource,這樣通過bindingSource1就實現了DataGridView和dsUser的數據綁定,也就是說在界面DataGridView上進行操作,可以同步到dsUser中(會在每行上打上標志)

 3 數據操作方法

  可以利用SqlDataAdapter批量更新DataTable中的數據庫,也支持表格中同時進行了刪除/修改和新增的操作,下面的代碼中,用select * from {0} where 1=2查詢語句為SqlDataAdapter提供架構:

 //生成架構
string selectSQL = string.Format("select * from {0} where 1=2", dt.TableName);
SqlDataAdapter sda = new SqlDataAdapter(selectSQL, ConnectionString)

 而後用SqlCommandBuilder自動構建新增/刪除/修改的命令,這樣就可以用sda.Update()方法對數據表進行批量操作了:

1 SqlCommandBuilder scb  =  new SqlCommandBuilder(sda);
2 sda.Update(dt);

 完整代碼如下:

1 public static void UpdateDataSet(DataSet ds, string tableName) 2 { 3 try 4 { 5 if (tableName == "") 6 { 7 throw new ArgumentNullException("tableName 不能為空"); 8 } 9 //生成架構 10 string selectSQL = string.Format("select * from {0} where 1=2", tableName); 11 using (SqlDataAdapter sda = new SqlDataAdapter(selectSQL, ConnectionString)) 12 { 13 14 SqlCommandBuilder scb = new SqlCommandBuilder(sda); 15 16 sda.UpdateCommand = scb.GetUpdateCommand(); 17 sda.InsertCommand = scb.GetInsertCommand(); 18 sda.DeleteCommand = scb.GetDeleteCommand(); 19 20 sda.Update(ds, tableName); 21 ds.Tables[tableName].AcceptChanges(); 22 DisposeCommand(sda.UpdateCommand); 23 DisposeCommand(sda.InsertCommand); 24 DisposeCommand(sda.DeleteCommand); 25 sda.Dispose(); 26 scb.Dispose(); 27 } 28 } 29 catch (SqlException e) 30 { 31 throw e; 32 } 33 } View Code

  為了確保在用戶編輯完成後,立刻將數據同步到數據集中,必須調用bindingSource的EndEdit方法來同步數據.

1 private void dataGridView1_CellEndEdit(object sender, DataGridViewCellEventArgs e)
2 {
3    this.bindingSource.EndEdit();
4 }

   在窗體加載時,調用刷新方法,然後程序會自動將數據綁定到DataGridView上:

1 private bool fnRefresh()
2 {
3     string sql = string.Format("select * from myUser");
4     CM.Products.DataAccess.SqlHelper.GetDataTableBySQL(this.dsUser.myUser, sql);
5     return true;
6 }

   我們可以通過DataGridView的EndEdit方法來獲取當前用戶是否已經結束編輯:

1 bool isEnd= this.dataGridView1.EndEdit();

   另外可以通過GetChanges()方法來獲取修改的數據,返回一個DataTable.

1 DataTable dtModify = this.dsUser.myUser.GetChanges(DataRowState.Modified);

  調用UpdateTable方法,即可對表格進行批量處理(這裡就一個表,如果是多個表,那麼需要指明表名):

 1 private bool Save()
 2 {
 3     try
 4     {
 5         DataAccess.SqlHelper.UpdateDataSet(this.dsUser, "myUser");
 6         this.dsUser.myUser.AcceptChanges();//提交數據庫
 7         return true;
 8     }
 9     catch (Exception ex)
10     {
11         return false;
12     }
13 
14 }

  當用戶選擇一個單元格時,會獲取到當前行的索引,然後調用RemoveAt()方法進行刪除,由於用bindingSource進行了綁定,可以直接調用save()方法進行數據保存:

 1 private void bindingNavigatorDeleteItem_Click(object sender, EventArgs e)
 2 {
 3     if (this.dataGridView1.CurrentRow != null)
 4     {
 5         int index = this.dataGridView1.CurrentRow.Index;
 6         if (index > -1)
 7         {
 8             this.dataGridView1.Rows.RemoveAt(index);
 9             Save();
10         }
11     }
12 }

  當用戶單擊新增按鈕時,我們創建一個強類型的myUserRow,然後給它附上默認值(特別是主鍵)

 1 //add row
 2 private void toolStripButton1_Click(object sender, EventArgs e)
 3 {
 4     Common.dsUser.myUserRow dr = this.dsUser.myUser.NewmyUserRow();
 5     dr["ID"] = System.Guid.NewGuid().ToString();
 6     dr["Name"] = "Name";
 7     dr["AddTime"] = DateTime.Now.ToString();
 8 
 9     this.dsUser.myUser.AddmyUserRow(dr);
10 }

 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved