处理 ClientDataset 的增量

Processing a ClientDataset's Delta

我一直在处理一些应该处理 TClientDataSet 的代码时遇到问题 Delta,我将其归结为以下测试用例。

我有两个 ClientDataSets,cdsData 和 cdsDelta,都有一个 DataSource,DBGrid 和 DBNavigator,以及用于显示 Delta 的旧值和新值的 TTreeView。

在 cdsDatas AfterPost 中,我调用了下面的 DisplayDelta 过程。

当我 运行 应用程序时,我更改并保存了 csdData 中一个字段的值, 比如,'PrevValue' 到 'UpdatedValue'。我的问题是 Treeview 中的 OldValue 和 NewValue 节点显示 'UpdatedValue' 和 没有 'PrevValue' 的迹象。那么,如何正确获取 OldValue 呢?

procedure TDeltaTestForm.DisplayDelta;
var
  Delta : OleVariant;
begin
  Delta := cdsData.Delta;
  if not VarIsClear(Delta) then begin
    cdsDelta.Data := Delta;
  end;
  if cdsData.Modified then
    Caption := 'modified'
  else
    Caption := '';
  Caption := Caption + '/' + IntToStr(cdsData.ChangeCount);
  BuildDeltaTree;
end;

procedure TDeltaTestForm.BuildDeltaTree;
var
  NewNode,
  ChildNode : TTreeNode;
  i,
  ID : Integer;
  Field : TField;
  Value : String;

  function ChildValue(ALabel : String; FieldValue : Variant) : String;
  begin
    Result := ALabel;
    if VarIsClear(FieldValue) then
      Result := Result + '(empty)'
    else
      if VarIsNull(FieldValue) then
        Result := Result + '(null)'
      else
        Result := Result + VarToStr(FieldValue);
  end;
begin
  { Find the current row in the delta dataset }

  ID := cdsData.FieldByName('ID').AsInteger;
  if not cdsDelta.Locate('ID', ID, []) then
    raise Exception.CreateFmt('ID: %d not found in Delta', [ID]);

  TreeView1.Items.BeginUpdate;
  try
    Treeview1.Items.Clear;
    for i:= 0 to cdsDelta.FieldCount - 1 do begin
      Field := cdsDelta.Fields[i];
      NewNode := TreeView1.Items.AddChild(Nil, Field.FieldName);
      ChildNode := TreeView1.Items.AddChild(NewNode, ChildValue('Old: ', Field.OldValue));
      ChildNode := TreeView1.Items.AddChild(NewNode, ChildValue('New: ', Field.NewValue));
      ChildNode := TreeView1.Items.AddChild(NewNode, ChildValue('Cur: ', Field.CurValue));
    end;
    TreeView1.FullExpand;
  finally
    TreeView1.Items.EndUpdate;
  end;
end;

我可以重现你的问题。试试这个:

改变

for i:= 0 to cdsDelta.FieldCount - 1 do begin
  Field := cdsDelta.Fields[i];

for i:= 0 to cdsData.FieldCount - 1 do begin
  Field := cdsData.Fields[i];

您现在应该会发现您获得了预期的 OldValueNewValue 值。无论如何,我在这里。

我承认我对此有些困惑 - 我一直假设您可以将一个 CDS 的 Delta 分配给另一个,而第二个将包含与 Delta 相同的字段值(旧的和新的),但显然不是。然而,这个结果与 Cary Jensen 出色的 "ClientDataSets"(第 6 章中的 "StatusFilter Versus Delta")的一段相吻合,他说:

" ...当您使用 CDS 的 Delta 加载第二个 CDS 时,第二个 CDS 没有更改缓存。"

也许他的意思是你在第二个中得到的是三角洲的快照,而不是它的历史。我想这就是为什么你的 cdsDelta returns 在 Field.OldValue 和 Field.NewValue.

中有相同的值