關於AdoQuery中的Refresh函數

首先看看Delphi的官方文檔中關於refresh的說明

Refetches data from the database to update a dataset抯 view of data.

procedure Refresh;

Description

Call Refresh to ensure that an application has the latest data from a database. For example, when an application turns off filtering for a dataset, it should immediately call Refresh to display all records in the dataset, not just those that used to meet the filter condition.

Note: The Refresh method does not work for all TDataSet descendants.In particular, TQuery components do not support the Refresh method if the query is not "live".To refresh a static TQuery, close and reopen the dataset.

TDataSet generates a BeforeRefresh event before refreshing the records and an AfterRefresh event afterwards.

Note: Most datasets try to maintain the current record position when you call refresh. However, this is not always possible. For example, the current record may have been deleted from the server by another user. Unidirectional datasets have no mechanism for locating the current record after a refresh, and always move back to the first record.

Warning: Unidirectional datasets refresh the data by closing and reopening the cursor. This can have unintended side effects if, for example, you have code in the OnClose or OnOpen event handlers.


注意我紅色標出的部分,如果我英文沒理解錯的話,就是Refresh會close,Open數據集,然後就會觸發OnClose OnOpen,甚至 BeforeClose,BeforeOpen事件。

就是這個東西把我搞死了。。。我Refresh一個數據集發現數據竟然改變了。排查了好久發現觸發了寫的BeforeOpen函數,其中將Filter清空了。

另外,注意的是Refresh的性能不好,會比較慢。Refresh會比較提取前後數據,然後進行改變。但是它刷新完後會重新定位到你原來的數據指針上。還有Refresh不會造成Grid閃動

在AdoQuery中還提供了Requery函數,同樣可以刷新,就是數據指針會回到第一個上,它的效果等同於先Close,再Open。

比較高性能的模仿Refresh的刷新數據方式有:

方法一:用書籤

var 
    SavePlace:   TBookmark; 
begin 
    SavePlace   :=   ADOQuery1.GetBookmark; 
    ADOQuery1.DisableControls; 
    ADOQuery1.Requery;     //與先Close再Open等效 
    ADOQuery1.GotoBookmark(SavePlace); 
    ADOQuery1.FreeBookmark(SavePlace); 
    ADOQuery1.EnableControls; //先定位再打開控件不會閃爍
end; 

    方法二、如果數據集有可唯一定位的關鍵字,如id,這樣做: 
var 
    id:   Integer; 
begin 
    id   :=   ADOQuery1.FieldByName( 'id ').AsInteger; 
    ADOQuery1.DisableControls; 
    ADOQuery1.Requery; 
    ADOQuery1.Locate( 'id ',   id,   []);  
    ADOQuery1.EnableControls;   
end; 
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章