Как остановить 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 Поле Истина. Это будет правда, если при входе в InternalOpenFieldCount из набора данных равен нулю. 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.

Другие вопросы по тегам