日韩黑丝制服一区视频播放|日韩欧美人妻丝袜视频在线观看|九九影院一级蜜桃|亚洲中文在线导航|青草草视频在线观看|婷婷五月色伊人网站|日本一区二区在线|国产AV一二三四区毛片|正在播放久草视频|亚洲色图精品一区

分享

ADO.NET中的多數(shù)據(jù)表操作淺析—修改...

 昵稱26780 2007-05-08
 

三、更新數(shù)據(jù)集

首先需要說明的是我這里去掉了Order Details表,對兩個(gè)表的操作只是其中的幾個(gè)字段。下面是窗體界面:



3-1

單選框用來選擇不同的更新方法。

DataAccess類中增加兩個(gè)類成員變量:

     private SqlDataAdapter _customerDataAdapter; //客戶數(shù)據(jù)適配器

     private SqlDataAdapter _orderDataAdapter; //訂單數(shù)據(jù)適配器

 

customerDataAdapter在構(gòu)造函數(shù)中的初始化為

//實(shí)例化_customerDataAdapter

SqlCommand selectCustomerComm = new SqlCommand("GetCustomer",_conn);

selectCustomerComm.CommandType = CommandType.StoredProcedure;

selectCustomerComm.Parameters.Add("@CustomerID",SqlDbType.NChar,5,"CustomerID");

        

SqlCommand insertCustomerComm = new SqlCommand("AddCustomer",_conn);

insertCustomerComm.CommandType = CommandType.StoredProcedure;

insertCustomerComm.Parameters.Add("@CustomerID",SqlDbType.NChar,5,"CustomerID");

insertCustomerComm.Parameters.Add("@CompanyName",SqlDbType.NVarChar,40,"CompanyName");

insertCustomerComm.Parameters.Add("@ContactName",SqlDbType.NVarChar,30,"ContactName");

 

SqlCommand updateCustomerComm = new SqlCommand("UpdateCustomer",_conn);

updateCustomerComm.CommandType = CommandType.StoredProcedure;

updateCustomerComm.Parameters.Add("@CustomerID",SqlDbType.NChar,5,"CustomerID");

updateCustomerComm.Parameters.Add("@CompanyName",SqlDbType.NVarChar,40,"CompanyName");

updateCustomerComm.Parameters.Add("@ContactName",SqlDbType.NVarChar,30,"ContactName");

             

SqlCommand deleteCustomerComm = new SqlCommand("DeleteCustomer",_conn);

deleteCustomerComm.CommandType = CommandType.StoredProcedure;

deleteCustomerComm.Parameters.Add("@CustomerID",SqlDbType.NChar,5,"CustomerID");

 

_customerDataAdapter = new SqlDataAdapter(selectCustomerComm);

_customerDataAdapter.InsertCommand = insertCustomerComm;

_customerDataAdapter.UpdateCommand = updateCustomerComm;

_customerDataAdapter.DeleteCommand = deleteCustomerComm;

 

上面的代碼完全可以用設(shè)計(jì)器生成,覺得有些東西自己寫感覺更好,不過代碼還是很多。

對于_orderDataAdapter的初始化同上面的差不多,這里我們只看訂單增加的處理,下面是存儲(chǔ)過程:

CREATE PROCEDURE  AddOrder

(

     @OrderID INT OUT,

     @CustomerID NCHAR(5),

     @OrderDate DATETIME

)

AS

INSERT INTO Orders

(

     CustomerID ,

     OrderDate

)

VALUES

(

     @CustomerID ,

     @OrderDate

)

--SELECT @OrderID = @@IDENTITY  //使用觸發(fā)器有可能出現(xiàn)問題

SET @OrderID = SCOPE_IDENTITY()

GO

 

OrderID自動(dòng)增長值的獲取通過輸出參數(shù)來完成,這個(gè)相當(dāng)不錯(cuò),如果使用SqlDataAdapter.RowUpdated事件來處理那效率會(huì)很低。

insertOrderComm對象的定義為:

SqlCommand insertOrderComm = new SqlCommand("AddOrder",_conn);

insertOrderComm.CommandType = CommandType.StoredProcedure;

insertOrderComm.Parameters.Add("@OrderID",SqlDbType.Int,4,"OrderID");

insertOrderComm.Parameters["@OrderID"].Direction = ParameterDirection.Output;

insertOrderComm.Parameters.Add("@OrderDate",SqlDbType.DateTime,8,"OrderDate");

insertOrderComm.Parameters.Add("@CustomerID",SqlDbType.NChar,5,"CustomerID");

 

在實(shí)現(xiàn)數(shù)據(jù)的更新方法之前我們先來明確一些更新邏輯:

對于標(biāo)記為刪除的行,先刪除訂單表的數(shù)據(jù),再刪除客戶表的數(shù)據(jù);

對于標(biāo)記為添加的行,先添加客戶表的數(shù)據(jù),再添加訂單表的數(shù)據(jù)。

 

1)實(shí)現(xiàn)用獲取修改過的DataSet的副本子集來更新數(shù)據(jù)的方法。

這也是調(diào)用Xml Web Service更新數(shù)據(jù)的常用方法,先來看第一個(gè)版本,子集的獲取通過DataSet.GetChangs方法來完成。

//使用數(shù)據(jù)集子集更新數(shù)據(jù)

public void UpdateCustomerOrders(DatasetOrders ds)

{            

     DataSet dsModified = ds.GetChanges(DataRowState.Modified);//獲取修改過的行

     DataSet dsDeleted = ds.GetChanges(DataRowState.Deleted);//獲取標(biāo)記為刪除的行

     DataSet dsAdded = ds.GetChanges(DataRowState.Added);//獲取增加的行

     try

     {   

         _conn.Open();//先添加客戶表數(shù)據(jù),再添加訂單表數(shù)據(jù)

         if(dsAdded != null)

         {

              _customerDataAdapter.Update(dsAdded,"Customers");

              _orderDataAdapter.Update(dsAdded,"Orders");

              ds.Merge(dsAdded);

         }

         if(dsModified != null)//更新數(shù)據(jù)表

         {

              _customerDataAdapter.Update(dsModified,"Customers");

              _orderDataAdapter.Update(dsModified,"Orders");

              ds.Merge(dsModified);

         }

         if(dsDeleted != null)//先刪除訂單表數(shù)據(jù),再刪除客戶表數(shù)據(jù)

         {

              _orderDataAdapter.Update(dsDeleted,"Orders");

              _customerDataAdapter.Update(dsDeleted,"Customers");

              ds.Merge(dsDeleted);

         }                 

     }

     catch(Exception ex)

     {

         throw new Exception("更新數(shù)據(jù)出錯(cuò)",ex);

     }

     finally

     {

         if(_conn.State != ConnectionState.Closed)

              _conn.Close();

     }

}

上面的方法看上去比較清晰,不過效率不會(huì)很高,至少中間創(chuàng)建了三個(gè)DataSet,然后又進(jìn)行了多次合并。

2)另一方法就是引用更新,不創(chuàng)建副本。

相對來說性能會(huì)高許多,但是如果用在Web服務(wù)上傳輸?shù)臄?shù)據(jù)量會(huì)更大(可以結(jié)合兩個(gè)方法進(jìn)行改進(jìn))。具體的實(shí)現(xiàn)就是通過DataTable.Select方法選擇行狀態(tài)來實(shí)現(xiàn)。

//引用方式更新數(shù)據(jù)

public void UpdateCustomerOrders(DataSet ds)

{

     try

     {   

         _conn.Open();

         //先添加客戶表數(shù)據(jù),再添加訂單表數(shù)據(jù)      _customerDataAdapter.Update(ds.Tables["Customers"].Select("","",DataViewRowState.Added));

     _orderDataAdapter.Update(ds.Tables["Orders"].Select("","",DataViewRowState.Added));

     //更新數(shù)據(jù)表

     _customerDataAdapter.Update(ds.Tables["Customers"].Select("","",DataViewRowState.ModifiedCurrent));

     _orderDataAdapter.Update(ds.Tables["Orders"].Select("","",DataViewRowState.ModifiedCurrent));

//先刪除訂單表數(shù)據(jù),再刪除客戶表數(shù)據(jù)

     _orderDataAdapter.Update(ds.Tables["Orders"].Select("","",DataViewRowState.Deleted));

     _customerDataAdapter.Update(ds.Tables["Customers"].Select("","",DataViewRowState.Deleted));           

     }

     catch(Exception ex)

     {

         throw new Exception("更新數(shù)據(jù)出錯(cuò)",ex);

     }

     finally

     {

         if(_conn.State != ConnectionState.Closed)

              _conn.Close();

     }

}

結(jié)合上面的兩個(gè)方法我們可想到調(diào)用Web Service有更合理的方法來完成。

3)使用事務(wù)

public void UpdateCustomerOrdersWithTransaction(DataSet ds)

{

     SqlTransaction trans = null;

     try

     {   

         _conn.Open();

         trans = _conn.BeginTransaction();

         _customerDataAdapter.DeleteCommand.Transaction = trans;

         _customerDataAdapter.InsertCommand.Transaction = trans;

         _customerDataAdapter.UpdateCommand.Transaction = trans;

         _orderDataAdapter.DeleteCommand.Transaction = trans;

         _orderDataAdapter.InsertCommand.Transaction = trans;

         _orderDataAdapter.UpdateCommand.Transaction = trans;

     _customerDataAdapter.Update(ds.Tables["Customers"].Select("","",DataViewRowState.Added));

                   _orderDataAdapter.Update(ds.Tables["Orders"].Select("","",DataViewRowState.Added));

     _customerDataAdapter.Update(ds.Tables["Customers"].Select("","",DataViewRowState.ModifiedCurrent));

     _orderDataAdapter.Update(ds.Tables["Orders"].Select("","",DataViewRowState.ModifiedCurrent));

     _orderDataAdapter.Update(ds.Tables["Orders"].Select("","",DataViewRowState.Deleted));

     _customerDataAdapter.Update(ds.Tables["Customers"].Select("","",DataViewRowState.Deleted)); 

          trans.Commit();

     }

     catch(Exception ex)

     {

         trans.Rollback();

         throw new Exception("更新數(shù)據(jù)出錯(cuò)",ex);

     }

     finally

     {

         if(_conn.State != ConnectionState.Closed)

              _conn.Close();

     }

}

最后讓我們來看看窗體的按鈕更新事件的代碼:

private void buttonUpdate_Click(object sender, System.EventArgs e)

{

              //提交編輯數(shù)據(jù)

     this.BindingContext[this._ds].EndCurrentEdit();

    

     if(radioButtonRef.Checked == true)//引用方式更新

         _dataAccess.UpdateCustomerOrders((DataSet)_ds);

     else if(radioButtonTrans.Checked == true)//啟用事務(wù)更新數(shù)據(jù)表

         _dataAccess.UpdateCustomerOrdersWithTransaction((DataSet)_ds);

     else

     {

         DatasetOrders changedData =  (DatasetOrders)_ds.GetChanges();

         if(radioButtonWeb.Checked == true)//Web服務(wù)的更正更新

         {                     

              _dataAccess.UpdateCustomerOrders((DataSet)changedData);

         }

         else//創(chuàng)建副本合并方式更新

         {                 

              _dataAccess.UpdateCustomerOrders(changedData);

         }

         //去除訂單表中添加的虛擬行

         foreach(DataRow row in _ds.Orders.Select("","",DataViewRowState.Added))

              _ds.Orders.RemoveOrdersRow((DatasetOrders.OrdersRow)row);

         //去除客戶表中添加的虛擬行

         foreach(DataRow row in _ds.Customers.Select("","",DataViewRowState.Added))

              _ds.Customers.RemoveCustomersRow((DatasetOrders.CustomersRow)row);

         _ds.Merge(changedData);

     }

     //提交數(shù)據(jù)集狀態(tài)

     _ds.AcceptChanges();

}

 

本文參考:《ADO.NET Core Reference 



Trackback: http://tb.blog.csdn.net/TrackBack.aspx?PostId=67037


    本站是提供個(gè)人知識(shí)管理的網(wǎng)絡(luò)存儲(chǔ)空間,所有內(nèi)容均由用戶發(fā)布,不代表本站觀點(diǎn)。請注意甄別內(nèi)容中的聯(lián)系方式、誘導(dǎo)購買等信息,謹(jǐn)防詐騙。如發(fā)現(xiàn)有害或侵權(quán)內(nèi)容,請點(diǎn)擊一鍵舉報(bào)。
    轉(zhuǎn)藏 分享 獻(xiàn)花(0

    0條評(píng)論

    發(fā)表

    請遵守用戶 評(píng)論公約

    類似文章 更多