如何直接使用DatasetAdapter的JSON导出,而不需要RESTRequest?

问题描述 投票:0回答:1

Delphi 提供了

DatasetAdapter
,以对象数组的形式将数据集导出和导入到标准 JSON,而没有
FDDataset.SaveToStream(Stream, sfJSON)
包含的所有怪异之处,从而产生更短、更干净的文件。

这是我将数据集导出和后期导入到简单 JSON 的快速演示:

  // We clear prior JSON export files
  if TFile.Exists('export.json') then
    TFile.Delete('export.json');

  // We create a source Dataset
  var LSource := TFDMemTable.Create(Self);
  LSource.CachedUpdates := True;
  LSource.FieldDefs.Add('id', ftInteger);
  LSource.FieldDefs.Add('description', ftWideString, 100);

  // We populate the source Dataset
  LSource.CreateDataSet;
  LSource.Append;
  LSource.FieldValues['id'] := 1;
  LSource.FieldValues['description'] := 'apples';
  LSource.Post;
  LSource.Append;
  LSource.FieldValues['id'] := 2;
  LSource.FieldValues['description'] := 'oranges';
  LSource.Post;

  // We create the objects to export that Dataset to JSON
  var LRequest := TRESTRequest.Create(Self);
  var LRequestAdapter := TRESTRequestDataSetAdapter.Create(Self);
  LRequestAdapter.Request := LRequest;
  LRequestAdapter.AutoUpdate := false;
  LRequestAdapter.Dataset := LSource;

  // We export the source Dataset to JSON
  LRequestAdapter.UpdateParameter;
  TFile.WriteAllText('export.json', LRequest.GetFullRequestBody);

  // We create a target Dataset
  var LTarget := TFDMemTable.Create(Self);
  LTarget.CachedUpdates := True;
  LTarget.FetchOptions.Items := [];
  LTarget.FieldDefs.Add('id', ftInteger);
  LTarget.FieldDefs.Add('description', ftWideString, 100);

  // We create the objects to import our JSON data to the target Dataset
  var LResponseAdapter := TCustomJSONDatasetAdapter.Create(Self);
  LResponseAdapter.Dataset := LTarget;
  
  // We import the JSON data to the target Dataset
  LResponseAdapter.UpdateDataSet(TJSONValue.ParseJSONValue(TFile.ReadAllText('export.json')));

  // We check that the target contains the same data we populated into the source
  ShowMessage('RowCount: ' + LTarget.RecordCount.ToString + ', First Row: ' + LTarget.FieldByName('Description').AsString);

它工作得很好,但我想知道 - 我可以避免在导出过程中使用中间

TRESTRequest
吗?大多数时候,我希望将生成的 JSON 放入 RAD 服务器的
TEndpointResponse
,而不是放入
TRESTRequest

DatasetAdapter
单元提供了
TCustomJSONDatasetAdapter
类,可以将直接JSON导入到数据集中,而无需从
TRESTResponse
读取它们。但我在该单元中找不到允许将数据集直接导出到 JSON 的类似类(因此我可以将该 JSON 放入
EndpointResponse
中,或进一步操作该 JSON,例如将其中几个保存到单个文件中以减少到后端的往返等)。我不想将该数据集导出到我真正不会使用的
TRESTRequest
体内,从而减慢进程并增加不必要的内存使用。

json delphi firedac delphi-11-alexandria
1个回答
0
投票

按照 Uwe Raabe 的建议,我使用底层 TDataSetToJSONBridge 类(Data.DBJson 单元)而不是 TRESTRequestDataSetAdapter,现在我可以直接获取导出 JSON。

  // We clear prior JSON export files
  if TFile.Exists('export.json') then
    TFile.Delete('export.json');

  // We create a source Dataset
  var LSource := TFDMemTable.Create(Self);
  LSource.CachedUpdates := True;
  LSource.FieldDefs.Add('id', ftInteger);
  LSource.FieldDefs.Add('description', ftWideString, 100);

  // We populate the source Dataset
  LSource.CreateDataSet;
  LSource.Append;
  LSource.FieldValues['id'] := 1;
  LSource.FieldValues['description'] := 'apples';
  LSource.Post;
  LSource.Append;
  LSource.FieldValues['id'] := 2;
  LSource.FieldValues['description'] := 'oranges';
  LSource.Post;

  // We export the source Dataset to JSON
  var ToJSONBridge := TDatasetToJSONBridge.Create;
  ToJSONBridge.Dataset := LSource;
  TFile.WriteAllText('export.json', ToJSONBridge.Produce.ToString);

  // We create a target Dataset
  var LTarget := TFDMemTable.Create(Self);
  LTarget.CachedUpdates := True;
  LTarget.FetchOptions.Items := [];
  LTarget.FieldDefs.Add('id', ftInteger);
  LTarget.FieldDefs.Add('description', ftWideString, 100);

  // We import the JSON data to the target Dataset
  var LResponseAdapter := TCustomJSONDatasetAdapter.Create(Self);
  LResponseAdapter.Dataset := LTarget;
  LResponseAdapter.UpdateDataSet(TJSONValue.ParseJSONValue(TFile.ReadAllText('export.json')));

  // We check that the target contains the same data we populated into the source
  ShowMessage('RowCount: ' + LTarget.RecordCount.ToString + ', First Row: ' + LTarget.FieldByName('Description').AsString);

简单多了,而且看起来效果很好。谢谢乌韦。

© www.soinside.com 2019 - 2024. All rights reserved.