DataSnap服务器方法不能直接返回TClientDataSet类实例,因为DataSnap不支持把TClientDataSet转化JSON对象,但是,DataSnap支持对TDBXReader的解析,我们可以在服务器端,利用TDBXReader的类方法,先把TClientDataSet实例转化为TDBXReader实例,然后把TDBXReader实例通过方法调用传到客户端,最后在客户端再利用TDBXReader的类方法,把接收到的TDBXReader实例转化为最终的TClientDataSet实例,大概思路就是这样。
先看服务器端代码,业务类申明如下:
{$METHODINFO ON}
TdmService = class(TDataModule)
SQLConnection1: TSQLConnection;
procedure DataModuleCreate(Sender: TObject);
procedure DataModuleDestroy(Sender: TObject);
private
{ Private declarations }
function GetData(sql: string): TDBXReader;
public
{ Public declarations }
function GetActions(PARENTID: string): TDBXReader;
end;
{$METHODINFO OFF}
//其中,私有函数GetData是个通用函数,其作用是返回参数sql语句的执行结果集。公共函数GetActions供用户端调用,返回符合条件的所有Actions记录。具体的实现如下:
function TdmService.GetActions(PARENTID: string): TDBXReader;
var
sql: string;
begin
sql := 'select * from actions where PARENTID=' + PARENTID;
Result := GetData(sql);
end;
function TdmService.GetData(sql: string): TDBXReader;
var
cmd: TDBXCommand;
Reader: TDBXReader;
LDataSet: TClientDataSet;
begin
cmd := SQLConnection1.DBXConnection.CreateCommand;
try
cmd.Text := sql;
Reader := cmd.ExecuteQuery;
LDataSet := TDBXDataSetReader.ToClientDataSet(nil, Reader, True);
Result := TDBXDataSetReader.Create(LDataSet, True);
finally
cmd.Free;
end;
end;
而在客户端,就是调用服务器方法,并转化返回值为TClientDataset:
procedure TForm2.Button1Click(Sender: TObject);
var
CallProxy: TdmServiceClient;
dr: TDBXReader;
begin
if ClientDataSet1.Active then
begin
ClientDataSet1.Close;
ClientDataSet1.FieldDefs.Clear;
ClientDataSet1.Fields.Clear;
ClientDataSet1.IndexDefs.Clear;
end;
CallProxy := TdmServiceClient.Create(SQLConnection1.DBXConnection);
try
dr := CallProxy.GetActions(Edit1.Text);
TDBXDataSetReader.CopyReaderToClientDataSet(dr, ClientDataSet1);
ClientDataSet1.Open;
finally
CallProxy.Free;
end;
end;
其中,TdmServiceClient是自动生成的服务器方法调用的代理类。