更改主记录时,为什么不发生TADOQuery AfterOpen事件?

时间:2019-03-28 15:44:21

标签: delphi ado delphi-xe3

请考虑我们有两个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

2 个答案:

答案 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;

SetDetailFilterRefreshParams都不涉及关闭和重新打开 明细数据集。 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对象的特定功能(也称为RequeryTCustomADODataSet的基础上检索匹配的详细记录,效率明显提高 而不是关闭并重新打开Detail数据集,这就是为什么不调用其AfterOpen事件的原因。

另请参阅在DB.Pas中定义的TDetailDatalinkTMasterDatalink

答案 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。

因此,不应触发打开事件,但在这种情况下某些数据访问组件会提供其他事件。

ref:FireDAC.Comp.DataSet.TFDDataSet.OnMasterSetValues