5

在 ClientDataSet 的 AfterPost 事件处理程序中,我需要当前记录的 ApplyUpdates 函数是否会执行更新或插入的信息。

AfterPost 事件将为新的和更新的记录执行,我不想声明一个新的 Flag 变量来指示“更新”或“插入”操作是否正在进行中。

示例代码:

procedure TdmMain.QryTestAfterPost(DataSet: TDataSet);
begin
  if IsInserting(QryTest) then
     // ShowMessage('Inserting')...
  else
     // ShowMessage('Updating');

  QryTest.ApplyUpdates(-1); 
end;

ApplyUpdate 完成后,应用程序将在 AfterPost 方法中写入日志。所以这个方法是最接近动作的地方,我更喜欢一个完全可以插入到这个事件处理程序中的解决方案。

如何使用 ClientDataSet 实例 QryTest 中的信息实现 IsInserting 函数?

编辑:我将尝试此处解释的 ClientDataSet.UpdateStatus 。

4

3 回答 3

6

ApplyUpdates 不会为您提供该信息 - 因为它可以是插入、更新和删除。

ApplyUpdates 应用存储在 Delta 数组上的更改信息。例如,该更改信息可以包含任意数量的不同类型的更改(插入、删除和更新),并且所有这些都将应用于同一个调用。

在 TDatasetProvider 上,您有 BeforeUpdateRecord 事件(或类似的事件, sleep 在内存上做了一些有趣的事情 :-) )。在将 Delta 的每条记录应用于底层数据库/数据集之前调用该事件,因此是获取此类信息的地方......但 Showmessage 将停止应用过程。

编辑:现在我记得还有另一个选项:您可以将 Delta 分配给另一个 clientdataset Data 属性并读取该记录的数据集 UpdateStatus。当然,您需要在执行 applyupdates之前执行此操作...

var
  cdsAux: TClientDataset;
begin
  .
  . 
  <creation of cdsAux>
  cdsAUx.Data := cdsUpdated.Delta;
  cdsAux.First;
  case cdsAux.UpdateStatus of
    usModified:
      ShowMessage('Modified');
    usInserted:
      ShowMessage('Inserted');
    usDeleted:
      ShowMessage('Deleted'); // For this to work you have to modify  
                              // TClientDataset.StatusFilter  
  end;
  <cleanup code>
end;
于 2009-07-08T08:21:20.547 回答
4

TDataSetProvider 上的 BeforeUpdateRecord 事件定义为:

procedure BeforeUpdateRecord(Sender: TObject;  SourceDS: TDataSet; DeltaDS:
                             TCustomClientDataSet; UpdateKind: TUpdateKind;
                             var Applied: Boolean);

参数UpdateKind说明将如何处理记录:ukModify, ukInsert or ukDelete。你可以像这样测试它:

procedure TSomeRDM.SomeProviderBeforeUpdateRecord(Sender: TObject;
      SourceDS: TDataSet; DeltaDS: TCustomClientDataSet; UpdateKind: TUpdateKind;
      var Applied: Boolean);
begin
  case UpdateKind of
    ukInsert :
         // Process Insert;
    ukModify :
         // Process update
    ukDelete :
         // Process Delete
  end;
end;

注意:这个事件签名来自Delphi 7。我不知道它是否在以后的Delphi版本中改变了。

于 2009-07-08T08:55:24.033 回答
3

将 ClientDataSet.StatusFilter 设置为 TUpdateStatus 值,然后读取 ClientDataSet.RecordCount

例如,

 ClientDataSet1.StatusFilter := [usDeleted];
 ShowMessage(IntToStr(ClientDataSet1.RecordCount));

将返回将要执行的删除查询的数量。

但是,请注意两件事。将 StatusFilter 设置为 usModified 始终包括已修改和未修改的记录,因此您取该值的一半(值 4 表示将执行 2 次更新查询)。此外,将 StatusFilter 设置为 [](一个空集)是您恢复到默认视图(修改、未修改和插入)的方式

确保在执行此操作之前已发布任何未发布的更改,否则可能不会考虑未发布的更改。

于 2009-07-10T20:45:09.677 回答