【问题标题】:How long does a TDataset bookmark remain valid?TDataset 书签的有效期是多久?
【发布时间】:2010-10-25 09:00:05
【问题描述】:

我正在工作的项目中有如下代码。

procedure TForm.EditBtnClick(Sender:TObject);
begin
  // Mark is form variable. It's private
  Mark = cdsMain.GetBookmark;
  // blabalbal
  .
  .   
  .
end;

procedure TForm.OkBtnClick(Sender:TObject);
var  
  mistakes: Integer;
begin
  //Validation stuff and transaction control
  //removed to not clutter the code
  If cdsMain.ChangeCount <> 0 then 
    mistakes := cdsMain.AppyUpdates(-1); 
  cdsMain.Refresh;
  try
    cdsMain.GotoBookmark(Mark);
    // Yes, I know I would have to call FreeBookmark
    // but I'm just reproducing 
  except
    cdsMain.First;
  end;
end;

就我个人而言,我很少使用书签——除了重新定位我只移动光标位置的数据集(创建列表、填充字符串列表等)。如果我Refresh、更新(尤其是当过滤器可以使记录不可见时)、重新获取(Close/Open)或任何修改数据集中数据的操作,我不使用书签。我更喜欢在主键上使用Locate(当然使用TClientDataset)或者重新查询修改参数。

书签的有效期到什么时候?直到Refresh?直到完成Close/Open 以重新获取数据?安全区在哪里结束?

请考虑在答案中我使用 TClientDatasetTSQLQuery (DbExpress)。

【问题讨论】:

    标签: delphi dbexpress tclientdataset


    【解决方案1】:

    就像 c0rwinskamradt 已经提到的那样:书签行为取决于您使用的 TDataSet 后代。

    一般来说,书签在以下期间失效:

    1. 关闭/打开
    2. 刷新(在支持它的数据集上)
    3. 数据更改(有时仅删除)

    我知道 1. 和 2. 会使您在 TClientDataSets 中的书签无效。我几乎可以肯定,对于 TClientDataSets,使用哪个底层提供程序(TSQLQuery、TIBQuery 等)并不重要。

    确定什么有效,什么无效的唯一方法是对其进行测试。 这意味着你不使用它们是完全正确的:书签有一个内在的不可靠的机会。

    为安全起见,请务必在访问书签之前致电BookmarkValid

    【讨论】:

    • 经过一些实验,即使是 BookmarkValid 也证明自己不可靠。当您在数据集上激活过滤器时会发生这种情况 - 即使记录与过滤条件不匹配,它也会返回 true。最终结果是抛出异常。
    【解决方案2】:

    TDataSet 实现了虚拟书签方法。虽然这些方法确保在调用书签方法时从 TDataSet 派生的任何数据集对象都返回一个值,但返回值只是默认值,不跟踪当前位置。 TDataSet 的后代,例如 TBDEDataSet,重新实现了书签方法以返回有意义的值,如下表所述:

    • BookmarkValid,用于确定指定的书签是否正在使用中。
    • CompareBookmarks,测试两个书签是否相同。
    • GetBookmark,为您在数据集中的当前位置分配书签。
    • GotoBookmark,返回到以前由 GetBookmark 创建的书签
    • FreeBookmark,释放以前由 GetBookmark 分配的书签。

    here获取它

    【讨论】:

    • 谢谢。我会改写这个问题,所以。
    • 不幸的是我不记得这个问题的答案了,因为我很久以前就离开了 Delphi 编程。我的直觉告诉我,在打开 DataSet 之前它应该是有效的,但是我可以想到即使在打开/关闭它之后它也可能有用的实现。我也倾向于同意下面的答案,因为它肯定取决于供应商。
    【解决方案3】:

    我个人很少使用书签。我改为使用我正在查看的记录的 ID,并在刷新完成后对其执行定位。如果我需要遍历集合中的所有记录,我会使用 tClientDataset 的克隆(它有自己的光标)来完成。

    据我了解,书签的实现取决于 tDataset 后代的供应商,并且可能因实现而异。在我非常简单的数据集 (tBinData) 中,我将书签实现为物理记录编号,因此只要记录未被删除,它就会在刷新之间持续存在。我不能对所有实现都这么说。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2023-03-30
      • 1970-01-01
      • 1970-01-01
      • 2021-07-20
      • 2016-10-21
      相关资源
      最近更新 更多