TDataSet EOF 循环逻辑似乎与文档不符

问题描述 投票:0回答:1

在搜索如何循环遍历 TDataSet 时,我发现了

使用 Eof 和 Bof 属性
。但是,我发现当通过
Eof
检索最后一条记录时,
Next()
变为 true,而不是在检索不存在的记录后,如文档所示。数据库是使用 FireDAC 的 SQLite。

基本上,这缺少最后一条记录:

dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;

dataset->First();
while (!dataset->Eof) {
  dataset->Edit();
  // ...
  dataset->Post();
  dataset->Next();
}
// oops - if there were 3 records the above loop only handled 2 of them, if I check
// the record returned after Next() it is the last record, only Eof is now true?

这有效(即使只存在 1 条记录):

dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;

dataset->First();
bool eof = dataset->Eof;
while (!eof) {
  dataset->Edit();
  // ...
  dataset->Post();
  eof = dataset->Eof;
  dataset->Next();
}

更新1:

好吧,这变得更有趣了。这有效:

dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;

dataset->First();
while (!dataset->Eof) {
  dataset->Next();
}

我注意到的一件事是处理记录的顺序与上面的不同。上面的内容按字母顺序排列,这就是网格当前排序的顺序。此过程在添加了多个记录的导入例程之后运行,因此它会按照网格中的顺序在最后一条记录上报告

Eof
,但是当使用
Edit()
/
Post()
时,它的顺序是不同的。换句话说,它添加了 3 项:

New eAcc Net

当它在不起作用的循环中处理它们时,它的顺序是:

eAcc New Net

在处理完

New
记录后,
Eof
报告为true,它将被排序。

那么,在禁用控件之前我可能需要做一些事情,或者延迟?还有其他人遇到过这个吗?你怎么处理?

更新2:

如果我只是设置

dataset->Filtered = false
,它就会按预期工作。我宁愿使用过滤器,也不愿处理每条记录并以这种方式检查字段。

在我看来,也许是因为我修复的条件不再存在,它对

Eof
是什么感到困惑,因为过滤器排除了它?也许只是一遍又一遍地打电话
First()

更新3:

是的,看起来这可行,但是有更好的方法吗?

dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;

dataset->First();
while (!dataset->Eof) {
  dataset->Edit();
  // ...
  dataset->Post();
  dataset->First(); // call first again instead of next since updated record no longer in filter.
}
c++builder tdataset
1个回答
0
投票

如果编辑记录的操作是从当前过滤器中删除记录,那么当编辑的记录被删除时,数据集中的下一条记录可能会成为新的活动记录。这在

Filtered
属性的文档中进行了说明:

注意:启用过滤后,用户对记录的编辑可能意味着该记录不再满足过滤器的测试条件。当过滤器生效时,下次尝试从数据集中读取记录时,该记录将不可见。如果发生这种情况,下一条通过过滤条件的记录将成为活动记录。

因此,也许尝试根本不在循环内寻找数据集

dataset->Filter = _D("MyFieldToSetDefaultValue is NULL");
dataset->Filtered = true;

dataset->First();
while (!dataset->Eof) {
  dataset->Edit();
  // ...
  dataset->Post(); // active record is removed from the filter
  // so, do not call First() or Next() here!
}
© www.soinside.com 2019 - 2024. All rights reserved.