【问题标题】:How to return DataSet from DataSnap server?如何从 DataSnap 服务器返回 DataSet?
【发布时间】:2019-02-03 13:58:23
【问题描述】:

大家好!我希望你能帮助我解决我的问题,但如果没有,谢谢你的尝试。我有 DataSnap 服务器和客户端。 DataSnap 服务器方法可以将 DataSet 作为函数结果返回给客户端。我正在使用 TFDQuery 组件从 MySQL DB 获取数据。有人请帮助我理解,我怎样才能从 FDQuery 组件中获取已经有数据的数据集?

TDataSet.Data 是包含所有数据的 OleVariant 类型属性。但是 FDQuery 没有相同的属性。我需要从 FDQuery 返回一个数据集作为函数中的 OleVariant。

*从代码中删除了 Try、Except、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;

需要任何有用的信息。提前致谢!祝你有美好的一天!

【问题讨论】:

    标签: delphi pascal firedac datasnap


    【解决方案1】:

    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 的数据)打包成可以在 ClientDataSet 之间发送的形式。将 DataSetProvider 合并到服务器中可以最大限度地减少客户端使用 CDS 数据所需的代码。

    顺便说一句,我假设您的服务器模块具有“导出”GetDataSet 作为服务器方法所需的代码。

    【讨论】:

      【解决方案2】:

      您也可以从服务器函数返回 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 服务器,您必须在此处使用 TsqlServerMethod(注意小写)“sql”,以及带有 TClientDatasetTDataSetProvider,所有这些都预先配置为从中检索数据服务器。

      如果是 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;
      

      【讨论】:

      • 谢谢 nolaspeaker,这个技巧很有帮助。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2023-03-12
      • 2011-11-05
      • 1970-01-01
      • 1970-01-01
      • 2011-05-18
      • 1970-01-01
      • 2011-05-02
      相关资源
      最近更新 更多