繁体   English   中英

TUniQuery (UniDac TUniQuery) Last 和 First 方法是直接跳转还是逐条记录滚动

[英]Does TUniQuery (UniDac TUniQuery) Last and First methods jump directly or do a record by record scroll

我有一个程序必须在用户转到数据集中的某个记录(TUniQuery)后设置一个更简单的屏幕。 用户可以通过多种方式跳转:combobox、搜索框,最后是 DbNavigator。 从第一个记录到最后一个记录需要很长时间。 在执行程序之后,我发现按下 DBNavigator 上的最后一个按钮会导致数据集上的每条记录都被访问,因此,在每条记录上,屏幕都是无用的。 从任何记录到第一个或最后一个记录都是一样的。 我的理解是,这样的方法( FirstLast )会直接跳转。 也许是 Unidac 组件上的一种特殊行为,但我找不到任何参考或属性来修改它。 目前,我计划在BeforeScroll事件上设置一个标志,但由于AfterScroll也发生在每个事件之后,我无法知道数据集何时结束滚动。 我在 Delphi 文档中也找不到任何简单说明的参考
调用 Last 以激活数据集中的最后一条记录

按照源代码,我发现了这个:
简短回答:是的,TDataset 尽可能直接跳转到第一条和最后一条记录,但是......

长答案:Delphi 具有广播的内部数据事件( DB单元, TDataEvent ),因此数据感知控件可以正确更新。 NextPrior和许多其他方法使用 function MoveBy ,它生成一个Before/AfterScroll事件和内部事件。 如果需要, MoveBy可能会获取一些额外的行。 假设您从 30 行数据集中提取了 20 行。 你目前的记录是十五。 你打电话给MoveBy(2) 不出所料,你的新纪录是十七岁。 在这种情况下,会发生以下情况:

  1. 滚动前
  2. ActiveRecord 递增两次(在循环中),但未获取任何行
  3. 内部数据事件:deDataSetScroll
  4. 后滚动

请注意,滚动时不会发生任何程序事件。 BeforeScroll出现在记录十五和AfterScroll在十七。

现在,同样的场景,但这次调用了MoveBy(10) 已经提取了五行(20 - 15),还需要检索另外五行。 在这种情况下,顺序是:

  1. 滚动前
  2. ActiveRecord 递增 5(在循环中),但未获取任何行
  3. 在同一个循环中,活动记录增加 5。 在每个循环中,获取一条记录(不发生程序事件)
  4. 内部数据事件:deDataSetChange
  5. 后滚动

每件事都运行良好。 不使用MoveBy并假定始终获取记录的Last方法会出现问题:

procedure TDataSet.Last;  
begin  
  CheckBiDirectional;  
  CheckBrowseMode;  
  DoBeforeScroll;  
  ClearBuffers;  
  try
    InternalLast;  
    GetPriorRecord;  
    GetPriorRecords;  
  finally  
    FEOF := True;  
    DataEvent(deDataSetChange, 0);  // Problem! Causes TJvDBSearchComboBox to retrieve all records (again)
    DoAfterScroll;  
  end;  
end;  

如您所见,即使所有记录都已获取, Last方法也始终广播deDataSetChange事件 在我的四个记录的特殊情况下,用户按下TDBNavigator的最后一个按钮,该按钮又调用Last方法。 广播deDataSetChange事件,然后TJvDBSearchComboBox (来自 JVCL 库)通过使用“while not eof...next”循环访问每一行来更新其内容并生成Before/AfterScroll事件来对此事件做出反应。

我喜欢 Delphi,但这是我不喜欢数据集的原因之一。 程序无法了解是否由于用户操作或程序本身触发了某些数据事件。 我在 Delphi 演示文稿中提出了一种在不触发事件的情况下遍历数据集的方法(如MoveBy所做的那样),然后,像TJvDBSearchComboBox这样的组件可以使用它,或者至少可以打开数据集中的标志等在开始访问每条记录之前。 此外, Last应该检查是否确实检索到了记录。

有些人会说这很容易由我自己实现,而且确实是当您的代码滚动浏览数据集时。 但在TDBNavigatorTJvDBSearchComboBox的情况下,我无法控制它们。 其他人会说不要使用 JVCL,这里没有简单的答案。 此外,仅供参考,一种方法表现出相同的行为。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM