Consider we have a standard master-detail relationship with two TADOQuery
. When navigation over master dataset takes place, an AfterOpen
event doesn't rise for the detail dataset.
This event is rised in other data access packages, such as BDE. Why does this behavior differ for dbGo?
A part of .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
The reason for the behaviour of the Delphi ADO components is that when the Master dataset scrolls, this code in ADODB.Pas executes
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;
and neither SetDetailFilter
nor RefreshParams
involves closing and re-opening
the Detail dataset. Requery
eventually calls
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;
which uses a specific capability (also named Requery
) of the ADO RecordSet object
underlying the TCustomADODataSet
to retrieve the matching detail records which is significantly more efficient
than closing and re-opening the Detail dataset, which is why its AfterOpen
event is not called.
See also TDetailDatalink
and TMasterDatalink
defined in DB.Pas.
This event is raised in other data access packages, such as BDE. Why does
this behavior differ for dbGo?
Most other data access packages do not raise the open events in this situation. For example the help for the FireDAC components mentions using OnMasterSetValues
(which is not available with the dbGo components):
Use the OnMasterSetValues event handler to override parameter values supplied to the detail dataset from the master dataset. Also, as the BeforeOpen and AfterOpen events do not fire for a detail dataset, OnMasterSetValues can be used instead.
So the open events aren't supposed to fire but some data access components provide other events in this situation.
ref: FireDAC.Comp.DataSet.TFDDataSet.OnMasterSetValues
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With