如何阻止TField.Origin重置

时间:2015-08-27 12:38:23

标签: delphi tfield

我使用TField.origin属性为SQL查询动态构建where子句。

所以,如果我有一个查询,如;

select
  p.firstname,
  p.lastname,
  g.description
from
  people p
  inner join groups g

我可以将firstname字段的来源设置为;

FirstNameField.origin = 'p.firstname';

然后在动态查询的where子句中使用它,例如;

SQLWhere = 'where ' + FirstNameField.origin + ' = ''' + MyValue + ''' ';

(显然我有额外的代码来防止SQL注入)。

我一直这样做,效果很好。然而,当我试图追踪一个错误时,我注意到我有一个数据集不断重置原点的值,例如回到;

people.firstname

而不是;

p.firstname

我将其追踪到数据集关闭然后重新打开的时间。但是我一直这样做,所以我无法理解为什么一个数据集有不同的行为。

我的问题是如何防止原点值被重置?

1 个答案:

答案 0 :(得分:3)

下面的代码来自D7的IBCustomDataSet单元(后面的代码更复杂 XEx版本)。

这段代码设置了IBX TField的Origin属性。

当数据集调用InternalOpen时,将调用TIBCustomDataSet.CreateFields 方法,如果其FDefaultFields字段为True。如果进入InternalOpen,它将为True 数据集的FieldCount为零。如果没有字段,FieldCount将为零 已使用“字段”编辑器在用户代码或IDE中预先创建 在数据集上。 TDataSet.Open通过其InternalOpen方法调用OpenCursor

因此,避免执行'CreateFields'的方法和数据集字段'Origin 因此重置属性是使用这些方法之一(IDE或用户代码) 在打开数据集之前创建字段。换句话说,如果您通过这些方法中的任何一种设置Origin属性,那么应该避免它被重置。

procedure TIBCustomDataSet.CreateFields;
var
  FieldAliasName, RelationName : String;
  i : Integer;
  f : TField;
begin
  inherited;
  for i := 0 to FQSelect.Current.Count - 1 do
    with FQSelect.Current[i].Data^ do
    begin
      { Get the field name }
      SetString(FieldAliasName, aliasname, aliasname_length);
      SetString(RelationName, relname, relname_length);
      f := FindField(FieldAliasname);
      if Assigned(f) then
      begin
        if (RelationName <> '') and (FieldAliasName <> '') then
          f.Origin := RelationName + '.' + FieldAliasName;
      end;
    end;
end;

更新在XE4和XE6之间显然改变了TIBCustomDataSet.InternalOpen的实现,因此现在无条件地调用CreateFields(即,无论DefaultFields是否为True)。因此,拥有已存在的TField将不会避免调用CreateFields,因此会重置Origin属性。