如何设置 TClientDataSet 字段名称和显示名称

How to set TClientDataSet field names and displayName

Delphi10.3

我正在尝试设置一个 TClientDataSet 以在我的测试中使用,但在添加字段后,Name 和 DisplayText 属性为空,并且 DisplayLabel 属性 具有 FieldName 属性。

class function TTestDataSetFactory.CreateTrainingCategoriesDataSet: TDataSet;
var
    DS : TClientDataSet;
    FMaxID : TAggregate;
begin
    DS := TClientDataSet.Create(nil);
    DS.Name := 'training_categories';

    with DS.FieldDefs do
    begin
        Add('id', ftInteger, 0, True);
        Add('category', ftString, 50, True);
        Add('description', ftString, 50, False);
    end;


    //Create function adds the aggregate to the DataSet. No more action needed
    FMaxID := TAggregate.Create(DS.Aggregates, DS);
    FMaxID.Expression := 'Max(id)';
    FMaxID.Active := True;
    FMaxID.Visible := True;
    FMaxID.DisplayName := 'MaxID';
    FMaxID.AggregateName := 'max_id';

    DS.CreateDataSet;

  DS.StoreDefs := True;

  DS.Open;

  DS.Fields[0].Name := 'id';
  DS.Fields[1].Name := 'category';
  DS.Fields[2].Name := 'description';

  DS.Fields[0].DisplayLabel := 'ID';
  DS.Fields[1].DisplayLabel := 'Category';
  DS.Fields[2].DisplayLabel := 'Description';

    DS.AggregatesActive := True;
    DS.Close;
    //Setup AutoInc, performed in AfterInsert event, with ID field (0)
    DS.AfterInsert := IncIdAtIndex0;
    Result := DS;
end;

快速测试:

procedure TTestDataSetFactoryTest.CreateTrainingCategoriesDataSet_ReturnsCorrectDataSet;
var
  DS : TDataset;
begin
  DS := TTestDataSetFactory.CreateTrainingCategoriesDataSet;
  DS.Open;

  CodeSite.Send( Format('Field 0 DisplayLabel = %s',[DS.Fields[0].DisplayLabel]) );
  CodeSite.Send( Format('Field 0 Name = %s',[DS.Fields[0].Name]) );
  CodeSite.Send( Format('Field 0 DisplayText = %s',[DS.Fields[0].DisplayText]) );

  Assert.AreEqual(3, DS.Fields.Count);

  Assert.AreEqual('id', DS.Fields[0].Name);
  Assert.AreEqual('category', DS.Fields[1].Name);
  Assert.AreEqual('description', DS.Fields[2].Name);

  Assert.AreEqual('ID', DS.Fields[0].DisplayName);
  Assert.AreEqual('Category', DS.Fields[1].DisplayName);
  Assert.AreEqual('Description', DS.Fields[2].DisplayName);

  DS.Close;
end;

Assert.AreEqual(3,DS.Fields.Count);通过,但所有 Name 和 DisplayText 属性都失败。

字段[0]记录这个

字段 0 DisplayLabel = id

字段 0 名称 =

字段 0 显示文本 =

将字段 属性 分配添加到测试中,一切都通过了,因此字段存在。

有谁知道为什么在数据集创建时没有设置字段属性?字段在那里。数据集的指定名称也可以。

提前致谢

加里

您必须像这样将 lcPersistent 分配给 LifeCycle 属性:

DS.Fields[0].LifeCycle    := lcPersistent;
DS.Fields[0].Name         := 'id';
DS.Fields[0].DisplayLabel := 'ID';

当然,对所有字段都执行相同的操作。

警告:字段属性 name 必须是唯一的,因为它用作必须唯一的组件名称。您可能应该结合数据集名称来构造它。

FPiette 给了你一个罚款和 up-to-date(使用最近的 TField.LifeCycle)答案来创建 来自 TFieldDefs 的 TField。我只想提一个不需要使用 TFieldDefs 的替代方案。

打开 TDataSet 时,将调用其 BindFields 方法,该方法将其 TFields 集合与 存储从数据文件中读取的记录的字段缓冲区。 如果字段不存在,它们是 当时创建的,但如果有,就不需要创建了。

这意味着像下面这样非常简单的代码就是创建和使用所需的全部 DataSet 的 TFields。创建具有持久所有者的 TFields 的简单步骤 - 在示例中,表单 - 确保它们在所有者的一生中都能持续使用。这就是使用字段编辑器(由 double-clicked 数据集的图标调用)在 IDE 中创建的持久性 TFields 的工作原理。

procedure TForm1.FormCreate(Sender: TObject);
var
  AField : TField;
begin
  AField := TIntegerField.Create(Self);
  AField.FieldKind := fkData;
  AField.FieldName := 'ID';
  AField.DataSet := ClientDataSet1;

  AField := TStringField.Create(Self);
  AField.FieldKind := fkData;
  AField.FieldName := 'AValue';
  AField.DataSet := ClientDataSet1;

  ClientDataSet1.CreateDataSet;

  ClientDataSet1.InsertRecord([1, 'One']);
  ClientDataSet1.InsertRecord([2, 'Two']);
  ClientDataSet1.InsertRecord([3, 'Three']);
end;