如何在设计时更改 Delphi FireDAC tFDMemTable 字段名称

问题描述

我尝试将 FDMemTable1field1 的字段名称“field1”更改为“field3”。没有代码,一切都在设计时完成。

TForm1 = class(TForm)
  DBGrid1: TDBGrid;
  DataSource1: TDataSource;
  FDMemTable1: TFDMemTable;
  FDMemTable1field1: TStringField;
  FDMemTable1field2: TStringField;

当通过 FDMemTable1 设计窗口中的弹出式菜单加载文件时,DBGrid1 显示数据良好。在对象检查器中将 'field1' 更改为 'field3' 会使 FDMemTable1.Active 为 'false' 并清除 DBGrid1 的所有单元格。

切换 FDMemTable1.Active 'true' 仅显示 DBGrid1 标题 'field3' 和 'field2' 而不是数据单元格。

最后加载相同的文件会触发错误 Field 'field3' not found. 即使我在停用 FDMemTable1 后更改名称,结果也是一样的。

是否可以在设计时更改字段名称?我应该将整个 'field1' 复制到 'field3' 并在运行时删除前者吗?

解决方法

我认为您想要的一个问题是,当 FDMemTable 中存储有数据时,您无法重命名 FDMemTable 中的字段,因为字段名称位于保存的数据中存储的元数据中。

也就是说,这是一个无需重命名 FDMemTable 字段的最小示例 丢弃存储在其中的数据。基本上,它以 XML 格式写出表的数据,将字段名称(在本例中为“FieldA”)更改为不同的名称(“FieldB”),并从更改后的 XML 文件中重新加载数据。

uses [...] FireDAC.Stan.StorageXML;

type
  TForm1 = class(TForm)
    FDMemTable1: TFDMemTable;
    DataSource1: TDataSource;
    DBGrid1: TDBGrid;
    Button1: TButton;
    FDStanStorageXMLLink1: TFDStanStorageXMLLink;
    procedure FormCreate(Sender: TObject);
  public
  end;

[...]

procedure TForm1.Button1Click(Sender: TObject);
var
  AFileName : String;
  TL : TStringList;
  S : String;
begin
  AFileName := 'C:\Temp\XMLData.XML';

  FDMemTable1.SaveToFile(AFileName,sfXML);
  TL := TStringList.Create;
  try
    TL.LoadFromFile(AFileName);
    FDMemTable1.Close;

    TL.Text := StringReplace(TL.Text,'FieldA','FieldB',[rfReplaceAll]);
    TL.SaveToFile(AFileName);

    DBGrid1.Columns.Clear;
    FDMemTable1.FieldDefs.Clear;
    FDMemTable1.Fields.Clear;
    FDMemTable1.LoadFromFile(AFileName,sfXML);
  finally
    TL.Free;
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
var
  Link : TFDStanStorageXMLLink;  //  This is needed to reload the data in XML format
  AField : TField;
begin

  Link := TFDStanStorageXMLLink.Create(Self);

  AField := TIntegerField.Create(Self);
  AField.FieldName := 'ID';
  AField.DataSet := FDMemTable1;

  AField := TStringField.Create(Self);
  AField.FieldName := 'FieldA';
  AField.Size := 32;
  AField.DataSet := FDMemTable1;

  FDMemTable1.CreateDataSet;

  FDMemTable1.InsertRecord([1,'One']);
  FDMemTable1.InsertRecord([2,'Two']);
end;

显然,如果您不想将数据写入文件系统,您可以使用临时流和 FDMemTable 的 SaveToStream 和 LoadFromStream。