所謂優化Master/Detail就是要讓Master/Detail的架構下能達到最佳效率化的目的,以InfoCommand與InfoDataSource所組成的Master/Detail關係下,如果在Client端的Master InfoDataSet的PackedRecord設為100時,此時假設每一筆Master相對的Detail筆數為10筆,則在Client端啟動InfoDataSet時會下載Master
100筆與Detail 1000筆的資料到Client端。
這樣在LAN的環境下是沒有感覺的,但如果是在Internet的環境中,那Client的效能將明顯的下降,因此我們要使用另一組獨立InfoCommand(Server端)與InfoDataset(Client端)作為一個顯示瀏覽的資料表(以下稱ViewDataSet),再以ViewDataSet獨立向Master取一筆資料與相對的Detail資料,來解決Internet環境下的效能問題。
q
設計Server端的View
Step1>延用S004 Project,從ToolBox中選另一個InfoCommand貼上,命名為View(Name的屬性設為【View】),將『CommandText』屬性設為【Select
[Purchases] .* from [Purchases]】(可以用【…】打開SQL Builder來設定SQL語法),再將『KeyFields』屬性設為【PurchaseID】。
圖
因為View不需要對資料進行新增更改刪除的操作,所以不需要貼上對應的的UpdateComp。這樣Server端就已經加好View的InfoCommand了。
Step2>直接Build(編譯)S004。
View的InfoCommand與Master的InfoCommand不同在於前者只有單一的Select語句,而Master因有InfoDataSource連接到不同的Detail上,所以除了Select Master的語句外,還會相對下多條Select
Detail(Where相對於Master的KeyValue)的語句,有多少筆Master就會下多少條Select Detail語句,因此啟動View比啟動Master來得輕省太多了。
q
設計Client端的View
Step1>打開Client端C004
Project,另外增加一個InfoDataSet和一個InfoBindingSource,分別命名為View和ibsView。
圖
Step2>將View的『RemoteName』屬性設為【S004.View】,將『Active』屬性設為【True】,將ibsView的『DataSource』屬性設為【View】(DataSet),『DataMember』屬性設為【View】(Table)。
圖
再來就是要設定View與Master間的關係。因InfoDataSet元件僅為資料的容器,用來容納Table的資料(可以容納多個Table資料),針對資料的操作(如上筆下筆的動作)必須透過InfoBindingSource來進行,因此我們必須設定ibsView這個InfoBindingSource來關連到Master這個InfoDataset,讓每移動一筆View就會使Master這個DataSet重新到Server上抓取相對的一筆資料,達到我們優化的目的。
Step3>點擊ibsView的Relations屬性右邊的小按鈕【…】,出現一個InfoRelation Collection Editor的視窗。
圖
Step4>在InfoRelation的視窗中點擊左下的【Add】按鈕,並選中新增的InfoRelation,將右邊的『Active』屬性設為【True】,表示啟動關連功能。再選擇右邊的『RelationDataSet』的屬性,這個屬性是設定關聯到哪個資料表,這裏選擇【Master】,代表當View移動時將重新啟動Master這個DataSet。
圖
Step5>有了View與Master的關係後,再來就是要設定其鍵值欄位關係(KeyFields)。接著按SourceKeyFields右邊的小按鈕【…】,出現InfoKeyField
Collection Editor視窗,按下【Add】按鈕,並選中新增的InfoKeyField,設定『FieldName』為【PurchaseID】,代表View的InfoBindingSource要以PurchaseID去重新啟動Master這個DataSet。
注:必要時可以設定多個的關係。
圖
Step6>接著同樣去設定TargetKeyFields屬性,設定對方的DataSet的Master Table將以哪一個欄位與SourceKeyFields對應,因為Master與View的Table都是同樣為Purchase,所以其KeyFields也都為PurchaseID,在此我們將『TargetKeyFields』也設為【PurchaseID】。
圖
Step7>將ibsView的『RelationDelay』設為【True】。
圖
這個屬性如果設為True,在User快速移動View的資料時,將不會去關聯(重新啟動)Master的資料,也就是User要停留在View的目前筆一段時間後,才會讓Master去抓取相對資料,這個延遲時間的長短是由DelayInterval屬性來決定的,系統預設為300毫秒(0.3秒)。這是一個人性化的效益設計,目的是為了讓Internet上的User能有較佳的操作資料的效能。
Step8>為了讓View可以顯示,我們在C004的頁面上貼入一個InfoDataGridView元件,並將原來Master的欄位往右調整(也可以整體複選移動與縮小)。如下圖。
圖
Step9>將新的InfoDataGridView的『DataSource』屬性為【ibsView】,並將其設為唯讀模式。(將Adding/Editing/Deleting的勾選去除)。
為了美觀,還可以將InfoDataGridView.SelectionMode設為FullRowSelect。
圖
接著只剩下InfoNavigator的調整,因為之前的InfoNavigator的上下筆對象是ibsMaster,但因為有了ibsView之後,其InfoNavigator的操作對象應該改成ibsView了。
Step10>因此我們必須在infoNavigator1這個InfoNavigator的『ViewBindingSource』屬性設定為【ibsView】,但原來的BindingSource還是為ibsMaster。
圖
這樣的結果會讓InfoNavigator在「查詢/上下筆/首末筆」等移動資料的功能是針對ibsView的,而「新增/編輯/刪除/確定/存檔」等功能還是針對原來的ibsMaster。這也是InfoNavigator的獨特功能。
Step11>最後必須將Master(InfoDataSet)的『Active』設為【False】。否則一開啟表單時,就會讓Master啟動而失去View優化的目的。
* 如果要讓C004表單打開時不下載任何資料,可以連同View的『Active』也跟著設為【False】,這樣系統一進入C004時,就會呈現空的表單(沒有資料),使用者必須使用「查詢」功能後才會有資料顯示在表單上,可再次增加系統的效能。
Step12>最後編譯C004。執行EEPNetClient.EXE並打開C004,查看結果。如圖,一進入系統時並沒有資料被下載,User必需先按「查詢」,再按【OK】後才會有資料顯示。而且每移動一筆View的資料,會立即到Server端去下載相對資料。
圖
最後,我們也可以打開SQL Profiler,來監看SQL語句,瞭解整個View與Master/Detail之間的優化關係。
圖
Related Topics