DataSnap ClientdataSet 三層中主從表的操作


非原創  摘自:http://hi.baidu.com/yagzh2000/blog/item/fc69df2cb9845de78b139946.html
三層中主從表的操作(刪除、新增、修改)一定要在一個事物中完成,那在Delphi中的事物又如何控制呢?我們在開發客戶端時,如果為了在一個事物中而用TSqlConnection的事物來控制是徒勞的,沒有一點意義,因為真正事物控制是在服務端的TDataSetProvider中產生的,它是自動產生事物的,如果有錯誤產生,它會回滾事物。

當客戶端的ClientdataSet把Delta數據提交給遠程的DataSetProvider時,這個DataSetProvider會解析這個語句,並且會自動產生一個事物,所以我們不必要寫事物控制,當然用函數時而不用DataSetProvider是另外一個話題。

如果我們直接在遠程端設置二個TDataSetProvider,客戶端也放兩個對就的ClientDataSet,並把客戶端的兩個數據集設置成主從可以嗎?
我的回答是:絕對不可以。為什么?因為你在更新數據時是在兩個DataSetProvider中產生二個不同的事物,這樣的話就不能保證數據更新的完整性。

Delphi為我們提供的機制是在服務端設置好主從結構,而從表數據集變為主表的一個字段,這樣當客戶端連接遠程的TDataSetProvider時,只把客戶端主表數據控件連接到DataSetProvider就可以,從表只要設置一下DataSetField為客戶端主表中那個數據集字段就可以了。當保存數據時,只用客戶端主表的ApplyUpdata就可以保存主從表數據(可以有多個從表)。更新時就把主從表相關改動的數據傳到遠程 的DataSetProvider中,些時DataSetProvider可以開啟一個事物,這樣就能保證數據的完整性。
以下我詳細說一下開發主從表的實例:
我用的數據集是:UniDac,它和Ado基本一樣用(用mssql2000 northwind 庫中的orders和order detail表做實例)
一.開發服務端
1. 放上連接數據庫的控件:UniConnection.和MSSQL驅動控件SQLServerUniProvider1(ADO不需要)
2. 放上主表數據集UniQuery1改為名稱 是Master,設置它的sql語句為:Select * From Orders
3. 放上主表數據集對應的DataSource,更名為DSMaster,設置這個數據源是為了讓從表和它關聯
4. 放上從表數據集UniQuery改為名稱是Detail,設置它的Sql語句為:Select * from [Order Detail] where orderid=:A(這個形參可以隨意設置)
5.設置Detail的MasterSource為DSMaster。再點選Detail屬性MasterFields,在彈出的對話框中把主從表的主鍵及子表的外鍵關聯起來。這樣就構成了主從關系結構。
6.在Master的AfterScroll事件中對Detail中的參數A賦值
 procedure TForm1.MasterAfterScroll(DataSet: TDataSet);
begin
Detail.Close;
Detail.Params[0].Value:=DataSet.FieldByName('orderid').AsInteger;
Detail.Open;
end;
        7.放入名為DSP的DataSetProvider控件,設置其DataSet為Master,並設置ResloveToDataSet為Ture,為Ture表示數據的處理交由和DataSetProvider的數據集來處理,可以處理多表的數據,為False表示產生的數據是由DataSetProvider的內置Sql分析器來處理 ,但不能處理多表數據。且記一定要打開。其它的屬性根據需要打開。

下圖為從表設置 的MaserFields屬性



二,客戶端設置(為了簡便測試,故把服務端和客戶端放在同一界面,所以不再設置ClientDataSet的RemoteServer屬性)

1.放入名為Main的ClientdataSet控件。
2.設置ClientDataSet的ProviderName為服務端的DSP.
3.在Main上打開字段屬性編輯器,並在編輯器中加入服務器端Master語句產生的字段
下圖為Main上的字段,你會發現有一個Detail的字段,它就是從表數據集,做為一個主表的字段了


4.再加入一個名為Child的ClientDataSet控件,它就是在客戶端的從表數據集控件。
5. 設置Child的DataSetField為"MainDetail",這是可選的,即它的數據是從Main數據集的Detail字段中得到的,其它的都不用設置。
如下圖


6.分別放兩個DataSource和DBgrid,並分別連接到Main和Child數據集和DBGrid中,這樣就可以顯示數據。

此時,我們就設置好了主從關系,你可以放上一些按鈕Open.代碼為:Main.Open.你就會發現當客戶端主表開啟時,從表也跟着開啟
如下圖

你可以更改、刪除、新增了。當然你要控制一下自增主鍵,這個不再多說。

還有一個發現的情況是服務端數據子表的ObjectView屬性,當設置Detail的ObjectView為True時,則子表的 SQL語句中不用參數,如:Select   * from [Order Detail]即可,當然那個主表數據集Master的AfterScroll中的代碼就不用要了,其它都不要改變,這樣的話也可以和 上面一樣的操作。這個屬性現在還不知是什么東東,請知道的告知一下,謝謝。
Ado中沒有這個屬性,但SqlQuery中有ObjectView這個屬性,我發現這個屬性挺重要的

另就是LookUp字段,如果要讓客戶端選擇的話,則是在客戶端的Child中設置它的LookUp字段,而在服務端設置成LookUP字段,則在客戶端只顯示而不能選擇;


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM