[英]Does TUniQuery (UniDac TUniQuery) Last and First methods jump directly or do a record by record scroll
我有一個程序必須在用戶轉到數據集中的某個記錄(TUniQuery)后設置一個更簡單的屏幕。 用戶可以通過多種方式跳轉:combobox、搜索框,最后是 DbNavigator。 從第一個記錄到最后一個記錄需要很長時間。 在執行程序之后,我發現按下 DBNavigator 上的最后一個按鈕會導致數據集上的每條記錄都被訪問,因此,在每條記錄上,屏幕都是無用的。 從任何記錄到第一個或最后一個記錄都是一樣的。 我的理解是,這樣的方法( First和Last )會直接跳轉。 也許是 Unidac 組件上的一種特殊行為,但我找不到任何參考或屬性來修改它。 目前,我計划在BeforeScroll事件上設置一個標志,但由於AfterScroll也發生在每個事件之后,我無法知道數據集何時結束滾動。 我在 Delphi 文檔中也找不到任何簡單說明的參考
調用 Last 以激活數據集中的最后一條記錄
按照源代碼,我發現了這個:
簡短回答:是的,TDataset 盡可能直接跳轉到第一條和最后一條記錄,但是......
長答案:Delphi 具有廣播的內部數據事件( DB單元, TDataEvent ),因此數據感知控件可以正確更新。 Next , Prior和許多其他方法使用 function MoveBy ,它生成一個Before/AfterScroll事件和內部事件。 如果需要, MoveBy可能會獲取一些額外的行。 假設您從 30 行數據集中提取了 20 行。 你目前的記錄是十五。 你打電話給MoveBy(2) 。 不出所料,你的新紀錄是十七歲。 在這種情況下,會發生以下情況:
請注意,滾動時不會發生任何程序事件。 BeforeScroll出現在記錄十五和AfterScroll在十七。
現在,同樣的場景,但這次調用了MoveBy(10) 。 已經提取了五行(20 - 15),還需要檢索另外五行。 在這種情況下,順序是:
每件事都運行良好。 不使用MoveBy並假定始終獲取記錄的Last方法會出現問題:
procedure TDataSet.Last;
begin
CheckBiDirectional;
CheckBrowseMode;
DoBeforeScroll;
ClearBuffers;
try
InternalLast;
GetPriorRecord;
GetPriorRecords;
finally
FEOF := True;
DataEvent(deDataSetChange, 0); // Problem! Causes TJvDBSearchComboBox to retrieve all records (again)
DoAfterScroll;
end;
end;
如您所見,即使所有記錄都已獲取, Last方法也始終廣播deDataSetChange事件。 在我的四個記錄的特殊情況下,用戶按下TDBNavigator的最后一個按鈕,該按鈕又調用Last方法。 廣播deDataSetChange事件,然后TJvDBSearchComboBox (來自 JVCL 庫)通過使用“while not eof...next”循環訪問每一行來更新其內容並生成Before/AfterScroll事件來對此事件做出反應。
我喜歡 Delphi,但這是我不喜歡數據集的原因之一。 程序無法了解是否由於用戶操作或程序本身觸發了某些數據事件。 我在 Delphi 演示文稿中提出了一種在不觸發事件的情況下遍歷數據集的方法(如MoveBy所做的那樣),然后,像TJvDBSearchComboBox這樣的組件可以使用它,或者至少可以打開數據集中的標志等在開始訪問每條記錄之前。 此外, Last應該檢查是否確實檢索到了記錄。
有些人會說這很容易由我自己實現,而且確實是當您的代碼滾動瀏覽數據集時。 但在TDBNavigator和TJvDBSearchComboBox的情況下,我無法控制它們。 其他人會說不要使用 JVCL,這里沒有簡單的答案。 此外,僅供參考,第一種方法表現出相同的行為。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.