我在我正在工作的项目中有如下代码。
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
重新获取数据之前?安全区在哪里结束?
在答案中考虑我使用TClientDataset
和TSQLQuery
(DbExpress)。
答案 0 :(得分:6)
就像c0rwin和skamradt已经提到的那样:书签行为取决于您使用的TDataSet后代。
通常,书签在以下期间无效:
我知道1.和2.可以使TClientDataSets中的书签无效。我几乎可以肯定,对于TClientDataSets,使用哪个底层提供程序(TSQLQuery,TIBQuery等)并不重要。
确保哪些有效,哪些无效的唯一方法。 这意味着你完全没有使用它们:书签具有不可靠的内在机会。
为了安全起见,请在转到书签前致电BookmarkValid
。
答案 1 :(得分:4)
我个人很少使用书签。我改为使用我正在查看的记录的id,并在刷新完成后对其执行定位。如果我需要迭代集合中的所有记录,我使用tClientDataset的克隆(它获得自己的光标)来做到这一点。
我的理解是书签的实现取决于tDataset后代的供应商,并且可以在实现之间变化。在我非常简单的数据集(tBinData)中,我实现了书签作为物理记录号,因此只要记录没有被删除,它就会在刷新之间保持不变。对于所有实现,我都不能这样说。
答案 2 :(得分:2)
TDataSet实现虚拟书签方法。虽然这些方法确保从TDataSet派生的任何数据集对象在调用书签方法时返回值,但返回值仅是不跟踪当前位置的默认值。 TDataSet的后代,例如TBDEDataSet,重新实现书签方法以返回有意义的值,如下面的列表所述:
从here
获取