#delphi #ado #delphi-xe3
#delphi #ado #delphi-xe3
Вопрос:
Рассмотрим, что у нас есть стандартная взаимосвязь master-detail с двумя 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
Ответ №1:
Причина поведения компонентов ADO Delphi заключается в том, что при прокрутке основного набора данных выполняется этот код в 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;
которое использует определенную возможность (также названную Requery
) объекта набора записей ADO
в основе TCustomADODataSet
лежит извлечение соответствующих подробных записей, что значительно эффективнее
чем закрытие и повторное открытие подробного набора данных, вот почему его AfterOpen
событие не вызывается.
Смотрите также TDetailDatalink
и TMasterDatalink
, определенные в DB.Pas.
Комментарии:
1. Спасибо! Отличное объяснение!
Ответ №2:
This event is raised in other data access packages, such as BDE. Why does
this behavior differ for dbGo?
Большинство других пакетов доступа к данным не вызывают события open в этой ситуации. Например, в справке для компонентов FireDAC упоминается использование OnMasterSetValues
(которое недоступно с компонентами dbGo):
Используйте обработчик события OnMasterSetValues, чтобы переопределить значения параметров, предоставленные в набор данных сведений из основного набора данных. Кроме того, поскольку события BeforeOpen и AfterOpen не запускаются для подробного набора данных, вместо этого можно использовать OnMasterSetValues .
Таким образом, события open не должны запускаться, но некоторые компоненты доступа к данным предоставляют другие события в этой ситуации.
Комментарии:
1. ? Но вопрос не в fDAC.
2. @MartynA Это указывает на то, что рассматриваемые события запускаются не более чем для dbGo и что некоторые компоненты предлагают альтернативное событие при изменении основной записи.
3. Но вопрос OP был почему . Кстати, не мое общее голосование.
4. @MartynA вопрос включает в себя «Это событие возникает в других пакетах доступа к данным, таких как BDE. Почему это поведение отличается для dbGo?» Мой ответ показывает, что первая часть неверна, что делает недействительной часть вопроса.
5. Спасибо! Я Раньше работал с BDE и одной внешней библиотекой, поэтому подумал, что это поведение по умолчанию.