TDataset的Lookup和Locate方法存在多久了?

5
我是一名有用的助手,可以为您进行翻译。以下是需要翻译的内容:

我正在修改和修复由他人编写的Delphi 4时代程序的代码库,使其现代化。从现代标准来看,很多代码看起来有点可怕,我不禁想知道,我所看到的其中一些情况是否是因为原始作者不了解某些标准库功能,或者这些功能当时还不存在。

在应用程序中遍布的更令人讨厌的“模式”之一如下所示:

table := TClientDataset.Create;
with table do
begin
  CloneCursor(dmDatabase.OriginalTable, false, true);
  filtered := true;
  active := true;
  first;
  while not EOF do
  begin
    if fieldByName('whatever').AsString = 'some criteria' then break;
    next;
  end;
  if EOF then exit;
  //do something based on the current row of the dataset
  table.free;
end;

几乎所有的这些组都可以被一个单行调用LookupLocate函数替代,而无需任何中间CDS。这让我想知道,在D4时代这些方法是否可用?LookupLocate是什么时候首次添加的?

如果未找到“某些条件”,则不会释放table吗? - JRL
@Jrl:就像我说的,按照现代标准,其中一些代码有点可怕。:P 但基本上是从记忆中重新创建为通用模式。try-finally块可能存在,也可能不存在。虽然有一些,但远远不如应该有的多。 - Mason Wheeler
1
这看起来像是由一个只学了足够的Delphi知识完成工作的人编写的代码,并且只知道一种(暴力方式)做事情的方法。即使在Delphi 1中,他也可以编写一个帮助函数,避免复制粘贴疾病。 - Warren P
我记得使用这种模式是因为在某些字段上,Locate函数不能按预期工作。现在不确定是哪些字段,也不确定这是否是编写此代码的动机... - EMBarbosa
2个回答

6

Lookup和Locate是在Delphi 2中引入的。看起来原作者只是没有充分利用它们。


3
+1;文件D2-CS-2.0\SOURCE\VCL\DB.PAS: 810 function Locate(const KeyFields: string; const KeyValues: Variant; - Jeroen Wiert Pluimers
5
为什么你手边有 Delphi 2 的 VCL 源代码可以这样搜索?D-: - afrazier
7
@afrazier:难道不是每个人都这样吗? :) - Bruce McGee
5
确认,绝对不是在Delphi 1 VCL中。我仍然拥有Delphi 1,因为我仍然支持一些16位应用程序。啊。我甚至仍然在Delphi 1和Delphi 2010之间交叉编译代码。试着用VB 3和VB.Net做到这一点吧! - Nat
@afrazier:因为我保留了旧版本的东西 :) 实际上:当帮助使用旧版 Delphi 的客户时,这非常方便。 - Jeroen Wiert Pluimers

6

看起来原始的程序员想要确保行指针根本没有被改变。使用Locate (或Lookup)会改变行指针,引发各种数据事件(Datasource.OnDataChange、Dataset.AfterScroll等)。

使用TClientDataset.CloneCursor进行搜索时,dmDatabase.OriginalTable不会触发任何这些事件,并且无需重新从数据库加载数据。

对我来说,这是一个意图。TClientDataset在D3中推出。而克隆游标是一种高级功能,需要将dmDatabase.OriginalTable做为CDS。


1
我可能会使用DisableControls/EnableControls和书签,而不是像这样为每个操作克隆游标。 - Bruce McGee
“Lookup” 不会改变行指针。“Locate” 会改变,但在一些情况下,这是在原始数据集上进行的,没有使用 CDS/“CloneCursor” 等内容,基本上是重新实现了“Locate”。 - Mason Wheeler
1
但是他们为什么没有在克隆上使用LocateLookUp呢? - Gerry Coll
另一个好问题:为什么这个(正如Mason所说)要在各个地方重复出现,而不是使用单个搜索函数?我知道这很可能 - 除了在(已故的)Delphi.net中使用预分配的vararrays会有麻烦之外 - 使用locate就可以实现 - 我甚至用这种方式完成了一个。 - Fabricio Araujo

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接