我使用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注入)。
我一直都在这么做,而且效果很好。然而,当我试图追踪一个bug时,我注意到我有一个数据集,它不断地将来源的值重新设置为;
people.firstname
而不是
p.firstname
我追踪到了数据集关闭然后重新打开的时间。然而,我一直在这样做,所以我不能理解为什么一个数据集有不同的行为。
我的问题是如何防止原始值被重置?
发布于 2015-08-28 01:41:29
下面的代码来自D7的IBCustomDataSet单元(在以后的XEx版本中,代码更加复杂)。
就是这段代码设置了IBX TField的Origin
属性。
如果dataset的FDefaultFields
字段为True,则在dataset调用其InternalOpen
方法时将调用TIBCustomDataSet.CreateFields。如果进入InternalOpen
时,数据集的FieldCount
为零,则为True。如果事先未在用户代码中或使用数据集上的字段编辑器在集成开发环境中创建任何字段,则FieldCount
将为零。InternalOpen
由TDataSet.Open通过其OpenCursor
方法调用。
因此,避免执行“CreateFields”和重置dataset字段的Origin
属性的方法是在打开dataset之前使用这些方法(集成开发环境或用户代码)创建字段。换句话说,如果您使用这两种方法中的任何一种来设置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;
更新 TIBCustomDataSet.InternalOpen的实现在XE4和XE6之间发生了明显的变化,因此现在可以无条件地调用CreateFields (也就是说,不管DefaultFields是否为真)。因此,已经存在的TFields并不能避免CreateFields被调用,从而重置原点属性。
https://stackoverflow.com/questions/32249639
复制相似问题