快速确定ClientDataSet是否有更改的方法

3

使用Delphi Berlin。

我在一个数据模块(“dmCore”)中有一个嵌套的Clientdataset。

对于任何给定的主记录,详细表中大约有5000条记录(使用2个主记录进行测试)。

我有一个连接到ActionManager中的操作的“Post”按钮。

它的OnUpdate很简单:

actPost.Enabled:=dmCore.HasChanges;// checks master for changes

"

"HasChanges"很简单:

"
function TdmCore.HasChanges: boolean;
begin
  result := False;
  if cdsPSet.Active then
     result:=(cdsPSet.ChangeCount>0);
end;

很遗憾,CDS.ChangeCount在onUpdate操作中运行占用了大量的CPU时间(>50%)。

我没有注意到这种情况发生在非嵌套的CDS上...

有没有更简单(更快)的机制可以用来检测CDS是否已经改变?我不需要计数,只需要知道某个地方发生了改变。

TIA EdB


1
我不确定我是否具备有效执行该任务的技能 - 我只是在试图做一些“愚蠢的标志技巧” - 在数据模块中设置一个布尔型“FastHasChanges”标志,并在数据可以更改的任何地方设置/清除该标志 - 然后只需检查该标志即可。这很丑陋,但完成起来相当快速。感谢您的建议,如果我突然有更多的空闲时间,我可能会尝试一下! - edbored
3个回答

2

尝试使用UpdatesPending属性。我无法保证它会更快,但这是检测数据集是否有任何更改的方法。所以在你的情况下,你实际上只需编写:

function TdmCore.HasChanges: boolean;
begin
  Result := cdsPSet.UpdatesPending;
end;

不幸的是,UpdatesPending 只在东京可用 - 我仍在使用柏林... - edbored
你说得对,它已经被添加到东京了(也许是因为你所描述的性能原因)。我错过了你的版本信息。抱歉。我能给你的最好建议就是尽快离开MIDAS。 - Victoria
比你想象的更糟糕:这个应用程序混合了CDS和FDQuery - 我正在使用需要CDS的高级网格,但是使用FDConnection->FDQuery->DataSetProvider->CDS。 - edbored
FireDAC的查询对象可以通过其UpdatesPending属性回答您(如果您直接使用它而没有提供程序)。问题(我认为会发生)是在这种情况下,缓存会出现在MIDAS的客户端数据集中。 - Victoria

1

在更新事件中切换操作的启用/禁用状态并不是最好的选择,因为它会一直触发。

您可能想将其移至 TDataSource.OnDataChanged 事件。在那里,您可以插入与 TAction.OnUpdate 中相同的代码,并且仅在数据实际更改时触发。您还可以使用 TField 参数来区分不同的字段。

示例(抱歉,我只有 C++ Builder,但在 Delphi 中看起来相同):

void __fastcall TForm1::DataSource1DataChange(TObject *Sender, TField *Field)
{
    Action1->Enabled = ClientDataSet1->ChangeCount > 0;
}

0

实现自己的失效机制。这很简单,只需要一个Boolean变量,当它为True时,表示有些东西已经改变了,当它为False时,表示没有任何改变。然后您将负责在对此数据集进行每次更改和操作时更新它。

如果是我,我会创建一个继承类,覆盖所有内容,并实现一个失效机制。它比现有方法要轻得多。当然,在设计时它不会像现有方法那样易于使用,但在运行时它可以完成工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接