TDataSet的EOF循环逻辑与文档不符问题排查
FireDAC连接SQLite时TDataSet遍历丢失最后一条记录的问题
我在查找TDataSet遍历方法时,参考了RAD Studio文档中的《Using the Eof and Bof Properties》,但发现用FireDAC连接SQLite时,调用Next()获取最后一条记录后EOF就变为true,和文档中“获取不存在的记录后才触发EOF”的描述不符。
问题代码(丢失最后一条记录)
dataset->Filter = _D("MyFieldToSetDefaultValue is NULL"); dataset->Filtered = true; dataset->First(); while (!dataset->Eof) { dataset->Edit(); // ... 此处处理字段逻辑 dataset->Post(); dataset->Next(); } // 问题:若有3条记录,上述循环仅处理2条,调用Next()后指向最后一条记录,但EOF已变为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
更有趣的是,仅调用Next()的循环可正常运行:
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(); // 因更新后的记录不再符合过滤条件,调用First而非Next }
内容的提问来源于stack exchange,提问作者user3161924
相关产品推荐
相关产品推荐

