Как вернуть DataSet с сервера DataSnap? - PullRequest
0 голосов
/ 03 февраля 2019

Привет всем, кто это читает!Я надеюсь, что вы можете помочь мне с моей проблемой, но если нет, спасибо за попытку.У меня есть сервер DataSnap и клиент.Методы сервера DataSnap могут возвращать клиенту DataSet как результат функции.Я получаю данные из базы данных MySQL с компонентом TFDQuery.Кто-нибудь, пожалуйста, помогите мне понять, как я могу получить набор данных из компонента FDQuery, в котором уже есть данные?

TDataSet.Data - это свойство типа OleVariant, содержащее все данные.Но FDQuery не имеет того же свойства.Мне нужно вернуть набор данных из FDQuery как OleVariant в функции.

* Попробуйте, кроме, FreeAndNil, DisposeOf и т. Д. Удалить из кода для лучшего понимания проблемы

//Client side
procedure TForm1.GetDataSetFromServer;
var
  Server: TServerMethods1Client;
  DS: TClientDataSet;
begin
  Server := TServerMethods1Client.Create(ClientModule1.SQLConnection1.DBXConnection);
  DS := TClientDataSet.Create(nil);   
  DS.Data := Server.GetDataSet; //Call remote server method
end;

//DataSnap server side
function TServerMethods1.GetDataSet: OleVariant;
begin
  FDQuery1.Close;
  FDQuery1.SQL.Text := 'SELECT * FROM Table1';
  FDQuery1.Open;
  //Now i need to return all data as function result
  result := ???
end;

Нужна любая информация, которая можетбыть полезным.Заранее спасибо!Хорошего дня!

Ответы [ 2 ]

0 голосов
/ 03 февраля 2019

Вы также можете вернуть TDataSet из функции сервера:

function TServerMethods1.GetDataSet: TDataSet;
begin
  if ClientDataSet1.Active then
    ClientDataSet1.Close;

  FDQuery1.Close;
  FDQuery1.SQL.Text := 'SELECT * FROM Table1';

  DataSetProvider1.DataSet := FDQuery1;
  ClientDataSet1.ProviderName := 'DataSetProvider1';
  ClientDataSet1.Open;
  Result := ClientDataSet1;
end;

Для клиентской стороны теперь это зависит от того, какой тип сервера вы используете.

Если это DBX Datasnap Server, вам придется использовать TsqlServerMethod (обратите внимание на нижний регистр) здесь 'sql' и TDataSetProvider с TClientDataset, все предварительно сконфигурированные для полученияданные с этого сервера.

Если это сервер REST Datasnap, вы можете сделать это на клиенте:

procedure TfrmClientMain.btnRefreshClick(Sender: TObject);
var
  Server: TServerMethods1Client;
  lDataSet: TDataSet;
  DSP: TDataSetProvider;
begin
  Server := TServerMethods1Client.Create(ClientModule1.DSRestConnection1);
  try
    CDS.Close; // a TClientDataSet has been placed on the form
    lDataSet := Server.GetDataSet();
    DSP := TDataSetProvider.Create(Self);
    try
      DSP.DataSet := lDataSet;
      CDS.SetProvider(DSP);
      CDS.Open;
    finally
      CDS.SetProvider(nil);
      DSP.Free;
    end;
 finally
   Server.Free;
 end;
end;
0 голосов
/ 03 февраля 2019

Самым простым способом сделать это, AFAIK, является добавление TDataSetProvider, а также TClientDataSet (если у вас его еще нет) в ваш серверный модуль.

Затем вы можете изменить код своего сервера следующим образом:

function GetDataSet: OleVariant;
begin
  if ClientDataSet1.Active then
    ClientDataSet1.Close;

  FDQuery1.Close;
  FDQuery1.SQL.Text := 'SELECT * FROM Table1';
  //  FDQuery1.Open; Leave this to the DataSetProvider/ClientDataSet

  //Now i need to return all data as function result
  //result := ???

  DataSetProvider1.DataSet := FDQuery1;
  ClientDataSet1.ProviderName := 'DataSetProvider1';
  ClientDataSet1.Open;
  Result := ClientDataSet1.Data;
end;

Смысл этого в том, что TDataSetProvider имеет все внутренние механизмы, необходимые для упаковки данных своего DataSet (т.е.Данные FDQuery1) в форме, которая может быть отправлена ​​между ClientDataSets.Включение DataSetProvider в сервер сводит к минимуму код, необходимый клиенту для использования данных CDS.

Кстати, я предполагаю, что ваш серверный модуль имеет код, необходимый для «экспорта» GetDataSet в качестве метода сервера.

...