bestlong 怕失憶論壇

 

 

搜索
bestlong 怕失憶論壇 論壇 Delphi 使用 TQuery 實作 master-detail 的注意事項
查看: 5207|回復: 0
go

使用 TQuery 實作 master-detail 的注意事項 [複製鏈接]

Rank: 9Rank: 9Rank: 9

1#
發表於 2007-3-7 10:32 |只看該作者 |倒序瀏覽 |打印
若 Master 與 Detail 都是使用 TQuery, 則當 Master 進入編輯狀態時,
Detail 資料表會被 Refresh (Close 然後 Open), 導致 detail 的
cursor 會跑到第一筆記錄(Delphi 3,4 皆如此),這對程式有什麼影響呢?

  1.你不能夠在 MasterQuery.AfterPost 中寫 DetailQuery.Post 及
    DetailQuery.ApplyUpdates, 這樣沒用, 而且 DetailQuery 中剛編
    輯的資料都會消失. 相反的,你必須在 MasterQuery.BeforePost 中
    撰寫儲存 DetailQuery 的程式碼(或者在 DetailQuery.BeforeClose
    中撰寫也可以). 這和一般認為應該先儲存 Master 再儲存 Detail
    的觀念剛好相反. 使用 TTable 則沒有這個情形.
    以下範例擷取自 Delphi online help, 示範在 DetailTable 的
    BeforeClose 事件中更新主細目資料表:

      procedure TForm1.DetailBeforeClose(DataSet: TDataSet);
      begin
        if Master.UpdatesPending or Detail.UpdatesPending then
        begin
          if Master.UpdateStatus = usInserted then
            Database1.ApplyUpdates([Master, Detail])
          else
            Database1.ApplyUpdates([Detail, Master])
        end;
      end;

  2.首先, 假設我們有這樣子的操作介面: 一個 master grid 及多個
    detail grid (你可能會用 PageControl 和一些按鈕一次開啟一個
    detail query 以加快速度), 而且這兩個 Grid 是同時顯示在同一個
    視窗, 你希望能夠以下列任何一種方式來編輯 detail 記錄:

    a) 雙擊 detail grid 或者以一個Edit按鈕開啟一個資料編輯視窗。
    b) DBNavigator。
    c) 直接在 detail grid 中編輯

    假設 detail 有三筆資料, 目前 cursor 停留在第二筆, 你可能會撰
    寫類似的程式碼:   

       MasterQuery.Edit;
       DetailQuery.Edit;

    你希望在使用者編輯 detail 資料時要由程式強制讓 master query
    進入 edit 狀態, 但是你會發現每次都是編輯到 DetailQuery 的第
    一筆紀錄, 原因就如之前所說, detail query 被 refresh 而將
    cursor 移至第一筆記錄.

    解決之道有兩種:

    a.由於這種問題只發生於 detail 也使用 TQuery 來存取的情形, 也
      就是說你可 將 detail table 都改用 TTable 來存取,ie. master
      table 以 TQuery 存取, detail tables 以 TTable 存取. 但使用
      TTable 做 detail 也有缺點:
      你不能任意指定其排序欄位, 它一定是用 foreign key 排序.
    b.使用 TBookmark. 在 master query 進入編輯狀態前記住目前
      detail query 的 cursor 位置, 並於 master query 進入編輯狀
      態後將 detail 的 cursor 移回先前記錄的位置. 加入此程式碼的
      最佳位置應該會是 detail query 的 BeforeEdit 事件. 這個方法
      實作上並不困難, 也保留了較大的彈性.
  3.當 master query 及 detail query 都處於編輯狀態, 你希望當執行
    MasterQuery.Cancel 時也同時取消 detail query 的編輯狀態, 不
    幸的是每當 master query 要 cancel 時會去尋找所有連結的資料集
    , 如果連結的資料集在編輯狀態中就會將他們儲存, 即使你在master
    query 的 BeforeCancel 中執行 DetailQuery.Cancel 也沒用, 因為
    剛才所說的動作是在 BeforeCancel 事件之前就執行的。

解決之道: 不要用資料感知元件, 如 TDBNavigator, 改用一般的 Button 來執行取消動作, 如此便可完全掌握 master 與 detail 執行動作的順序了.
我是雪龍
http://blog.bestlong.idv.tw
http://www.bestlong.idv.tw
‹ 上一主題|下一主題

Archiver|怕失憶論壇

GMT+8, 2024-6-13 18:42 , Processed in 0.009730 second(s), 10 queries .

Powered by Discuz! X1.5

© 2001-2010 Comsenz Inc.