Как остановить TField.Origin от получения сброса
Я использую свойство TField.origin для динамического построения предложения where для SQL-запросов.
Так что, если у меня есть запрос, такой как;
select
p.firstname,
p.lastname,
g.description
from
people p
inner join groups g
Я могу установить источник поля имени в;
FirstNameField.origin = 'p.firstname';
Затем используйте это в предложении where динамических запросов, таких как;
SQLWhere = 'where ' + FirstNameField.origin + ' = ''' + MyValue + ''' ';
(очевидно, у меня есть дополнительный код для предотвращения SQL-инъекций).
Я делаю это все время, и это прекрасно работает. Однако, пытаясь отследить ошибку, я заметил, что у меня есть один набор данных, который продолжает сбрасывать значение источника, например обратно;
people.firstname
вместо;
p.firstname
Я проследил это до того момента, когда набор данных был закрыт, а затем снова открыт. Однако я делаю это все время, поэтому не могу понять, почему один набор данных ведет себя по-разному.
У меня вопрос, как я могу предотвратить сброс исходного значения?
1 ответ
Приведенный ниже код взят из модуля IBCustomDataSet D7 (код более сложен в более поздних версиях XEx).
Именно этот код устанавливает Origin
собственность IBX TField.
TIBCustomDataSet.CreateFields будет вызываться, когда набор данных вызывает его InternalOpen
метод, если его FDefaultFields
Поле Истина. Это будет правда, если при входе в InternalOpen
FieldCount
из набора данных равен нулю. FieldCount
будет равен нулю, если поля не были созданы заранее, либо в коде пользователя, либо в IDE с использованием редактора полей в наборе данных. InternalOpen
вызывается TDataSet.Open через его 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;
Обновление Реализация TIBCustomDataSet.InternalOpen была явно изменена между XE4 и XE6, так что теперь CreateFields вызывается безоговорочно (т.е. независимо от того, имеет ли значение DefaultFields значение True). Следовательно, наличие уже существующих TFields не предотвратит вызов CreateFields и, следовательно, сбрасывает свойства Origin.