1. 程式人生 > >ClientdataSet 三層中主從表的操作

ClientdataSet 三層中主從表的操作

摸索了好久,終於找到了3層主從表設定的方法,為了紀念這些天來的努力,記上日記,也為不瞭解的朋友來學習,如果有什麼不對的地方則給我留言。
三層中主從表的操作(刪除、新增、修改)一定要在一個事務中完成,那在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.你就會發現當客戶端主表開啟


時,從表也跟著開啟


如下圖


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



還有一個發現的情況是子表的 SQL


語句中不用引數,如:Select   * from [Order Detail]即可,當然那個主表資料集Master的AfterScroll中的程式碼就


不用要了,其它都不要改變,這樣的話也可以和 上面一樣的操作。也行!!


另就是LookUp欄位,如果要讓客戶端選擇的話,則是在客戶端的Child中設定它的LookUp欄位,而在服務端設定成


LookUP欄位,則在客戶端只顯示而不能選擇.