TClientDataSet.ApplyUpdates(0) 之前是否需要执行 CheckBrowseMode/Post



我在Delphi 2009(Firebird 3.0(中有TIBQuery-TDataSetProvider-TClientDataSet链,我执行MyClientDataSet.ApplyUpdates(0(。在调用 ApplyUpdates(0( 之前,我是否需要调用 CheckBrowseMode 或在此 CDS 上发布。我几乎可以肯定我需要调用Post/CheckBrowseMode,我认为未发布的更新不会应用于IBQuery,我没有支持/反对这种想法的文档,但这样认为是合乎逻辑的。但有时我可以观察到 MyClientDataSet 在 ApplyUpdates(0( 之前处于 [dsInsert, dsEdit] 状态,并且新值仍然发布并保存在查询中。但也有证据和理由反对这一点。所以 - 我很困惑。

当然,我不对TIBQuery使用CachedUpdate(因为有CDS(,这不是关于提交事务的问题,我强烈控制它们,并且排除了该问题。

我做了测试:我把raise Exception放在MyClientDataSet的BeforePost事件中,MadException给出了跟踪:

TMyDM.MyClientDataSetBeforePost
TDataSet.DoBeforePost
TDataSet.Post
TCustomClientDataSet.Post
TDataSet.CheckBrowseMode
TCustomClientDataSet.ApplyUpdates

因此,有经验证据表明,CheckBroseMode是自动调用的,但它是偶然的(例如,由于DataSetProvider或ClientDataSet的一些特殊配置(,还是我可以在文档中找到的规则?

还是我可以在文档中找到的规则?

有一个更简单的规则,应该是不言而喻的,我会想:如果CDS的状态是dsEdit或dsInsert,人们可能会认为它处于更改挂起状态 - 已经进行了更改(例如,在数据库感知控件中(但尚未写回CDS的记录缓冲区(如果它具有嵌套数据,则为缓冲区(。 Otoh,调用 ApplyUpdates 的目的是通过 DSP 将记录缓冲区中的更改写回源数据集。 因此,当CDS在dsEdit/dsInsert中时,不应该尝试调用ApplyUpdates,这似乎是基本的。 在任何情况下,CheckBrowse 模式由 TCustomClientDataSet.ApplyUpdates 调用:

function TCustomClientDataSet.ApplyUpdates(MaxErrors: Integer): Integer;
var
  RootDataset: TCustomClientDataset;
begin
  CheckBrowseMode;
  RootDataset := Self;
  while RootDataset.FParentDataSet <> nil do
    RootDataset := RootDataset.FParentDataset;
  with RootDataset do
    if ChangeCount = 0 then
      Result := 0 else
      Reconcile(DoApplyUpdates(Delta, MaxErrors, Result));
end;

值得注意的是,如果数据集的状态是 dsEdit 或 dsInsert,则 CheckBrowseMode 会执行以下三项操作之一:

  • 除了调用 CheckActive 然后调用 DataEvent(deCheckBrowseMode, 0( 之外,什么都没有, 如果数据集的状态不是 dsEdit、dsInsert 或 dsSetKey
  • 如果当前记录已被修改,则调用 Post
  • 否则呼叫取消。

过程 TDataSet.CheckBrowseMode; 开始 检查活动; DataEvent(deCheckBrowseMode, 0(; 案例状态 dsEdit, dsInsert: 开始 更新记录; 如果修改,则发布其他取消; 结束; dsSetKey: 发布; 结束; 结束;

最新更新