请考虑我们有两个TADOQuery
的标准主从关系。在主数据集上进行导航时,明细数据集不会发生AfterOpen
事件。
此事件在其他数据访问包(例如BDE)中引发。为什么dbGo的这种行为不同?
.dfm的一部分:
object DataSource1: TDataSource
DataSet = SDQuery1
Left = 504
Top = 72
end
object DataSource2: TDataSource
DataSet = SDQuery2
Left = 520
Top = 360
end
object ADOConnection1: TADOConnection
LoginPrompt = False
Left = 336
Top = 464
end
object ADOQuery1: TADOQuery
Connection = ADOConnection1
Parameters = <>
Left = 504
Top = 160
end
object ADOQuery2: TADOQuery
Connection = ADOConnection1
AfterOpen = ADOQuery2AfterOpen // <- rised when dataset was opened at first time only
DataSource = DataSource1
Parameters = <>
Left = 520
Top = 296
end
答案 0 :(得分:6)
之所以使用Delphi ADO组件,是因为当 主数据集滚动,此代码在ADODB.Pas中执行
procedure TCustomADODataSet.MasterChanged(Sender: TObject);
begin
if not Active then Exit;
if Parameters.Count = 0 then
begin
CheckBrowseMode;
if SetDetailFilter then First;
end else
RefreshParams;
end;
,SetDetailFilter
和RefreshParams
都不涉及关闭和重新打开
明细数据集。 Requery
最终致电
procedure TCustomADODataSet.InternalRequery(Options: TExecuteOptions = []);
begin
if FConnectionChanged then
DatabaseError(SCantRequery);
try
Recordset.Requery(ExecuteOptionsToOrd(Options));
except
if Recordset.State = adStateClosed then Close;
raise;
end;
DestroyLookupCursor;
end;
,它使用ADO RecordSet对象的特定功能(也称为Requery
)
TCustomADODataSet
的基础上检索匹配的详细记录,效率明显提高
而不是关闭并重新打开Detail数据集,这就是为什么不调用其AfterOpen
事件的原因。
另请参阅在DB.Pas中定义的TDetailDatalink
和TMasterDatalink
。
答案 1 :(得分:3)
This event is raised in other data access packages, such as BDE. Why does
this behavior differ for dbGo?
在这种情况下,大多数其他数据访问包都不会引发打开事件。例如,FireDAC组件的帮助提到使用OnMasterSetValues
(dbGo组件不提供):
使用OnMasterSetValues事件处理程序覆盖参数值 从主数据集提供给明细数据集。另外,作为 对于详细数据集,不会触发BeforeOpen和AfterOpen事件, 可以使用OnMasterSetValues。
因此,不应触发打开事件,但在这种情况下某些数据访问组件会提供其他事件。