考虑我们与两个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
Delphi ADO组件行为的原因是当Master数据集滚动时,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
都不涉及关闭和重新打开Detail数据集。 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;
它使用Requery
底层的ADO RecordSet对象的特定功能(也称为TCustomADODataSet
)来检索匹配的详细记录,这比关闭和重新打开Detail数据集明显更有效,这就是为什么不调用它的AfterOpen
事件。
另请参见DB.Pas中定义的TDetailDatalink
和TMasterDatalink
。
This event is raised in other data access packages, such as BDE. Why does
this behavior differ for dbGo?
在这种情况下,大多数其他数据访问包不会引发打开事件。例如,FireDAC组件的帮助提到使用OnMasterSetValues
(dbGo组件不可用):
使用OnMasterSetValues事件处理程序覆盖从主数据集提供给detail数据集的参数值。此外,由于不会为详细数据集触发BeforeOpen和AfterOpen事件,因此可以使用OnMasterSetValues。
因此,开放事件不应该触发,但是一些数据访问组件在这种情况下提供其他事件。