Delphi 在顶层以下加载和保存嵌套的clientdataset数据的正确方法是什么?

Delphi 在顶层以下加载和保存嵌套的clientdataset数据的正确方法是什么?,delphi,tclientdataset,Delphi,Tclientdataset,我正在设计一个使用三层clientdataset的程序,顶层:cdsMaster,有两个嵌套层:cdsTables和cdsNotes。在使用过程中,程序应该创建结构,并在运行时在cdsmaster中发布一条记录。我的意图是,用户随后将通过在DBgrid中提供输入或使用cdsTables.LoadFromFile和cdsSavetoFile方法选择以前保存的文件来填充cdsTables和cdsNotes字段。我想跳过主级数据,在cdsTables级(包括其cdsNotes)保存/加载记录,每个表存

我正在设计一个使用三层clientdataset的程序,顶层:cdsMaster,有两个嵌套层:cdsTables和cdsNotes。在使用过程中,程序应该创建结构,并在运行时在cdsmaster中发布一条记录。我的意图是,用户随后将通过在DBgrid中提供输入或使用cdsTables.LoadFromFile和cdsSavetoFile方法选择以前保存的文件来填充cdsTables和cdsNotes字段。我想跳过主级数据,在cdsTables级(包括其cdsNotes)保存/加载记录,每个表存储在单独的文件中。每次用户选择包含嵌套cdsNotes数据的cdsTables文件时,必须将其作为新的cdsTables记录添加到cdsMaster中。下面是clientdataset结构的示例,但不包括嵌套级别中实际包含的许多字段

unit datamod_u;

interface

uses
  System.SysUtils, System.Classes, Data.DB, Datasnap.DBClient;

type
  TDataMod = class(TDataModule)
    cdsMaster: TClientDataSet;
    cdsTable: TClientDataSet;
    cdsNotes: TClientDataSet;
    procedure DataModuleCreate(Sender: TObject);
  private
    { Private declarations }
  public
    { Public declarations }
    procedure DefinecdsMaster;
    procedure DefineCdsTable;
    procedure LoadTable (fname: string);
    procedure SaveTable (fname: string);
  end;

var
  DataMod: TDataMod;

implementation

{%CLASSGROUP 'Vcl.Controls.TControl'}

{$R *.dfm}

procedure TDataMod.DefineCdsMaster;
begin
  with TstringField.Create(Self) do
  begin
    Name := 'cdsMstrName';
    FieldKind := fkData;
    FieldName := 'Name';
    DataSet := cdsMaster;
  end;
  with TDataSetField.Create(Self) do
  begin
    Name := 'cdsMstrTbls';
    FieldKind := fkData;
    FieldName := 'Tables';
    DataSet := cdsMaster;
//    Required := True;
    Visible := false;
  end;
end;

procedure TDataMod.DefineCdsTable;
begin
  cdsTable.DataSetField :=  TDataSetField(cdsMaster.FieldByName('Tables'));
  with TstringField.Create(Self) do
  begin
    Name := 'cdsTblName';
    FieldKind := fkData;
    FieldName := 'Tbl Name';
    DataSet := cdsTable;
    Required := false;
  end;
  with TDataSetField.Create(Self) do
  begin
    Name := 'cdsTblNotes';
    FieldKind := fkData;
    FieldName := 'Notes';
    DataSet := cdsTable;
  end;

  cdsNotes.DataSetField :=  TDataSetField(cdsTable.FieldByName('Notes'));

  with TstringField.Create(Self) do
  begin
    Name := 'cdsNote';
    FieldKind := fkData;
    FieldName := 'Note';
    DataSet := cdsNotes;

  end;
end;

procedure TDataMod.DataModuleCreate(Sender: TObject);
begin
  DefineCdsMaster;
  DefineCdsTable;
  cdsMaster.CreateDataSet;
  cdsMaster.edit;
  cdsMaster.FieldByName('Name').AsString := 'MasterList';
  cdsMaster.post;
end;
end.

Cary Jensen的书《Delphi深入,Clientdatsets第二版》指出,SavetoFile和LoadfromFile方法只能在顶层使用,不能在嵌套层使用。因此,问题变成了如何最好地将嵌套级别的数据保存/加载到文件中。一种方法可能是创建一个与cdsMaster的嵌套级别(cdsTables和cdsNotes)具有相同结构的临时clientdataset,并将每个记录字段复制到临时组件中,这样我就可以使用SavetoFile/LoadfromFile方法。那似乎有点不雅。我一直找不到在实践中说明这类操作的例子。有人能举例说明如何做到这一点吗?

您是否添加了第二个和第三个ClientDataSet,并通过DatasetField属性将它们连接到嵌套的数据集?。然后,您应该能够在相应的clientdataset上使用SaveToFile保存嵌套的数据集。SaveToFile方法将所有表保存到同一个文件中。我想将各个表记录保存到单独的文件中。根据该程序的性质,不同的用户将无法访问同一主文件,并且每个用户只需要某些表记录。在设计方面,将表限制为用户手动选择的较小组是有意义的。如果嵌套ClientDataSet上的SaveToFile保存了所有表,则可以尝试创建详细数据集的克隆(MyCloneDataset.CloneCursor(MyDetailDataset)),并在该克隆上调用SaveToFile。