How to pass TDataset parameter

Hello,

I have a query on client side, TDbisamQuery in particular, and i need to pass the resultset over to server side, as method parameter.

What would be the best way of doing that?

Thanks.

You can’t pass TDataset descendant as parameter but you can serialize it to stream with datastreamer and read it from stream on other side.

  • you can get IDADataset from TDataset descendant with TDatasetWrapper
  • write IDADataset to stream with any datastreamer like TDABin2DataStreamer
  • pass stream to other side.
  • read data from stream to TDAMemDataTable
  • TDataset descendant can be accessed like table.Dataset

Thanks Evgeny, any sample code available for using TDatasetWrapper?

just create it?

//ds: idadataset
//mydataset : tdataset;
ds:= TDatasetWrapper.Create(mydataset);

Arghh okay thank you.

Would you advice how to do this properly please?
//ADataset: TDataset
Client side:

   vDS := TDatasetWrapper.Create(ADataset);
   vDataset := Binary.Create;
   vDataStreamer := TDABin2DataStreamer.Create(NIL);
   try
      vDataStreamer.Initialize(vDataset, aiWrite);

      vDataStreamer.WriteDataset(vDS, [woRows, woSchema]);

      vResult := (RoutingService as IIdlsRoutingService).UpdateRouting(vDataset, -1, vErrorMessage);
   finally
      vDataStreamer.Finalize;
      vDataStreamer.free;
      //vDS.free;
   end;

Server side. First method parameter is of Binary type:

function TIdlsRoutingService.UpdateRouting(const ADataset: Binary; const AUpdUserID: Integer; out AErrorMessage: string): Boolean;
   var vMDT: TDADataTable;
       vIdx: integer;
begin
   vMDT := DatatableFromStream(ADataset, TDADataTable, DABin2DataStreamer1);
   try
      for vIdx := 0 to vMDT.Dataset.Fields.Count-1 do
         CodeSite.SendString('Field', vMDT.Dataset.Fields[vIdx].FieldName)
   finally
      vMDT.free
   end
end;

according to your task, I’d suggested to you just pass array of strings. it will be more simple and clear solution:

  • fill array on client side
  • pass it to server-side
  • process them

No, i need to be able to use the code on server-side which deals with TDataset.

The above code on server-side is just a testing to see how the dataset is passed.

check that DatatableFromStream returns TDAMemDataTable object

I see that the routine returns TDADataTable, but even if i change it accordingly it AVs.

var vMDT: TDADataTable;
vIdx: integer;
begin
vMDT := DatatableFromStream(ADataset, TDADataTable, DABin2DataStreamer1);
try
for vIdx := 0 to vMDT.Fields.Count-1 do
CodeSite.SendString(‘Field’, vMDT.Fields[vIdx].Name)
finally
vMDT.free
end
end;

Can you clearly show what is wrong with the code, without asking me to keep guessing?

vMDT := DatatableFromStream(ADataset, TDADataTable, DABin2DataStreamer1);

specify TDAMemDataTable here

I tried that already.

Is it the only issue with the code that you see?

client-side:
your stream isn’t written correctly. correct usage is

      vDataStreamer.Finalize;
      vResult := (RoutingService as IIdlsRoutingService).UpdateRouting(vDataset, -1, vErrorMessage);


in testcases we use this code:

    LStream:= TMemoryStream.Create;
    try
      DABin2DataStreamer1.WriteDataset(LStream, DAMemDataTable1, [woSchema], -1);
      LStream.Position:= 0;
      LTestTable:= TDAMemDataTable.Create(nil);
      try
        DABin2DataStreamer1.ReadDataset(LStream, LTestTable, True);
        Check(CompareBytes(LTestKey, LTestTable.ParamByName('blob1').AsBytes));
      finally
        FreeAndNil(LTestTable);
      end;
    finally
      FreeAndNil(LStream);
    end;

Thanks Evgeny, .Finalize was a culprit.