Чтение структуры DataSet без чтения данных - PullRequest
3 голосов
/ 23 февраля 2010

Scenerio:

Я хочу добавить вычисляемое поле к данному (любому) набору данных во время выполнения. Я не знаю другого способа получить структуру набора данных, кроме выполнения метода DataSet.Open.

Но метод Open приводит к тому, что по крайней мере одну строку данных необходимо передавать с сервера на клиент. Затем мне нужно закрыть DataSet, добавить поле и снова открыть его. Это ненужные накладные расходы, на мой взгляд. Есть ли лучший способ сделать это? Обратите внимание, что я хочу иметь возможность добавлять вычисляемое поле к любому набору данных и не знаю его структуру до открытия.

В псевдокоде это выглядит так:

DataSet.Open;
DataSet.Close;
RecreateFieldsStructure;
AddCalculatedField;
DataSet.Open;

Спасибо за ваше время.

Ответы [ 2 ]

12 голосов
/ 23 февраля 2010

Вы можете использовать метод DataSet.FieldDefs.Update. Это все еще будет включать некоторую передачу данных, но строки не будут выбраны. Вы можете вызвать этот метод в событии BeforeOpen TDataSet, а также добавить туда вычисляемые поля.

Вот короткий пример, который работает для меня:

procedure TDataModule.cdsExampleBeforeOpen(DataSet: TDataSet);
var I: Integer;
    TmpField: TDateTimeField;
begin
  // Get field definitions from the server
  DataSet.FieldDefs.Update;

  // Add calculated field
  TmpField := TDateTimeField.Create(DataSet);
  with TmpField do
  begin
    Name := 'Date';
    FieldName := 'Date';
    DisplayLabel := 'Date';
    DisplayFormat := 'ddd ddddd';
    Calculated := True;
  end;
  TmpField.DataSet := DataSet;

  // Create fields from field definitions
  for I := 0 to DataSet.FieldDefs.Count - 1 do
    DataSet.FieldDefs[I].CreateField(DataSet);
end;
3 голосов
/ 23 февраля 2010

Если я хорошо понимаю ваш вопрос; Вы хотите увидеть / узнать структуру таблиц перед вызовом метода ADOQuery (open). если это то, что вы хотите, вы можете использовать методы ADOConnection, такие как (GetFieldNames) и вот пример того, как получить имена полей таблицы (EMP):

procedure TForm2.Button1Click(Sender: TObject);
var
  lstFields: TStringList;
begin
  lstFields := TStringList.Create;
  try
    ADOConnection1.GetFieldNames('EMP', lstFields);
  finally
    lstFields.Free;
  end;
end;

тогда все имена полей теперь включены (lstFields). Я надеюсь, что это поможет.

С уважением.

...