5
votes

Can I access the parent dataset information (like MyField.NewValue) in the BeforeUpdateRecord event of a provider when applying the updates to the nested dataset?

Reason:

When I apply updates to a CDS that has a nested detail, the master PK is generated by the underlying query (TIBCQuery) and propagated to the master CDS.

But the new key is not visible in the BeforeUpdateRecord of the detail as the field is updated in the AfterUpdateRecord:

DeltaDS.FieldByName(FieldName).NewValue := SourceDS.FieldByName(FieldName).NewValue) 

and the delta is not merged yet.

It looks like the DeltaDS parameter of the BeforeUpdateRecord event contains only information to the nested dataset when the call occurs for the details.

It would be nice if I could do something like:

DeltaDS.ParentDS.FieldByName('FIELDNAME').NewValue.

Edit:

When using nested datasets the BeforeUpdateRecord event is called twice, once for the master and once for the detail (if we have one record of both). When the event is called for the detail, is there a way to access the master information contained in the DeltaDS ?

We can't access the data of the master CDS at that moment as the changes are not already merged. I hope this is not adding more confusion.

1
I am sure it is me, but could you please rephrase the question?Andrea Raimondi

1 Answers

3
votes

You can use the provider's Resolver to look up the corresponding TUpdateTree:

function FindDeltaUpdateTree(Tree: TUpdateTree; DeltaDS: TCustomClientDataSet): TUpdateTree;
var
  I: Integer;
begin
  Result := nil;
  if Tree.Delta = DeltaDS then
    Result := Tree
  else
    for I := 0 to Tree.DetailCount - 1 do
    begin
      Result := FindDeltaUpdateTree(Tree.Details[I], DeltaDS);
      if Assigned(Result) then
        Break;
    end;
end;

You can use this in your OnBeforeUpdate handler:

var
  Tree, ParentTree: TUpdateTree;
begin
  if SourceDS = MyDetailDataSet then
  begin
    Tree := FindDeltaUpdateTree(TDataSetProvider(Sender).Resolver.UpdateTree, DeltaDS);
    if Assigned(Tree) then
    begin
      ParentTree := Tree.Parent;
      // here you can use ParentTree.Source (the dataset) and ParentTree.Delta (the delta)
    end;
  end;
end;