Delphi:如何通过delta访问clientdataset

时间:2016-08-08 00:45:39

标签: delphi tclientdataset

在TDatasetProvider.OnBeforeUpdateRecord上,我该怎么做 访问源的或源自clientdataset 发送DeltaDS参数?

procedure TdmLoanPayment.dpLoanPaymentBeforeUpdateRecord(Sender: TObject;
    SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind:  TUpdateKind;
    var Applied: Boolean);
var
  sourceCDS: TClientDataset;
begin
  sourceCDS := DeltaDS.???;
  ...
end;

我需要从相应的clientdataset访问一些属性。安装程序是TSQLDataset / TDatasetProvider / TClientDataset。

修改 所有这些麻烦的原因是,我想从TDatasetProvider派生一个组件并分配一个默认的OnBeforeUpdateRecord。

2 个答案:

答案 0 :(得分:0)

我认为SourceDS正在寻找。

  

发件人参数标识正在应用更新的提供商。

     

SourceDS 参数是发起数据的数据集。   如果没有源数据集,则此值为nil(Delphi)或NULL   (C ++)。事件发生时,源数据集可能不处于活动状态,因此   在尝试访问其数据之前,将其Active属性设置为true。

     

DeltaDS 参数是包含所有更新的客户端数据集   正在应用。当前记录代表更新   即将应用。

     

UpdateKind 参数指示此更新是否为   修改现有记录(ukModify),插入新记录   (ukInsert),或要删除的现有记录(ukDelete)。

     

已应用参数可控制退出事件后发生的情况   处理程序。如果事件处理程序将Applied设置为true,则为提供程序   忽略更新:它既不会尝试应用它,也不会记录更新   指示未应用更新的错误。如果是事件处理程序   leaves应用为false,提供程序尝试在之后应用更新   事件处理程序退出。

例如:

procedure TdmLoanPayment.dpLoanPaymentBeforeUpdateRecord(Sender: TObject;
SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind:  TUpdateKind;
var Applied: Boolean);
begin
  ShowMessage(TClientDataSet(SourceDS).Name); // get source name
  ...
end;

修改

  procedure TdmLoanPayment.dpLoanPaymentBeforeUpdateRecord(Sender: TObject;
SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind:  TUpdateKind;
var Applied: Boolean);
begin
  if SourceDS.Name = 'Name1'then
    ...do something ...
  if SourceDS.Name = 'Name2'then
    ...do something ... 
end;

答案 1 :(得分:0)

如果你追踪到DataSetProvider1BeforeUpdateRecord的电话,你就可以了 看到作为SourceDS参数传递的数据集是Source数据集 UpdateTree,即AFAICS,DataSet属性的数据集 提供商设置为。当然,这是Delta的 CDS 已派生(在我的测试用例中,它实际上是一个TAdoQuery)。

查看Provider.Pas中的源代码,我无法立即看到 找到Delta的源CDS的身份的方法。我认为这并不特别令人惊讶,因为提供商的操作是由CDS调用的,而不是相反,并且提供商从CDS需要的所有数据都是其Delta。

另一方面,这是一个相当公平的赌注,即BeforeUpdateRecord事件 是由最新的,仍在等待的,在你的一张CDS上调用ApplyUpdates触发的,所以如果 你可能会在BeforeApplyUpdates事件中记下这一点 告诉你你想知道什么。我希望这可以用于单级更新,但如果UpdateTree在嵌套CDS上运行,则可能会更棘手。

如果您的CDS都有各自的提供商,但提供商共享BeforeUpdateRecord事件,您可以使用以下代码识别给定提供商的CDS:

function TCDSForm.FindCDSForProvider(DataSetProvider: TDataSetProvider):
    TClientDataSet;
var
  i : Integer;
begin
  Result := Nil;
  for i := 0 to ComponentCount - 1 do begin
    if Components[i] is TClientDataSet then
      if TClientDataSet(Components[i]).ProviderName = DataSetProvider.Name then begin
        Result := TClientDataSet(Components[i]);
        Exit;
      end;
  end;
end;