【问题标题】:How to set TClientDataSet field names and displayName如何设置 TClientDataSet 字段名称和 displayName
【发布时间】:2020-09-17 03:39:34
【问题描述】:

德尔福 10.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 属性均失败。

Field[0] 记录这个

字段 0 DisplayLabel = id

字段 0 名称 =

字段 0 显示文本 =

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

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

提前致谢

加里

【问题讨论】:

  • Close() DS 字段被销毁后。您必须在Open() 之后定义DisplayLabel
  • Fwiw,DS.AfterInsert 不是处理 autoinc 行为的正确方法 - OnNewRecord 事件是处理此问题的正确位置。
  • 另外,afaik 从来不需要间接创建 FieldDef 来反过来创建 TField。您可以直接在代码中创建 TField,并给它们一个 TPersistent Owner 使它们也可以持久化。简单。
  • MartynA 感谢 OnNewRecord 提示。当我想在我的程序中实际使用 AfterInsert 时,我会遇到麻烦。

标签: delphi tclientdataset


【解决方案1】:

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

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

当然,对所有字段都做同样的事情。

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

【讨论】:

  • fpiette,这正是我想要的!我试过 DS.StoreDefs := True;但显然这不起作用。谢谢
【解决方案2】:

FPiette 为您提供了一个很好且最新的(使用最近的 TField.LifeCycle)答案来创建 来自 TFieldDefs 的 TFields。我只想提一个不需要使用 TFieldDefs 的替代方案。

当一个 TDataSet 打开时,它的 BindFields 方法被调用,它将它的 TFields 集合与 存储从数据文件读取的记录的字段缓冲区。 如果字段不存在,它们是 在当时创建,但如果他们这样做了,则不需要创建它们。

这意味着只需要创建和使用以下非常简单的代码即可 DataSet 的 TFields。创建具有持久所有者的 TField 的简单步骤 - 在示例中,表单 - 确保它们在其所有者的一生中持续存在。这就是使用字段编辑器(通过双击 DataSet 的图标调用)在 IDE 中创建的持久 TField 的工作原理。

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;

【讨论】:

  • MartynA,谢谢,但我在测试中使用数据集来模拟真实的 MYSQL 表,所以没有持久所有者,没有表格只是一个参考
  • 当然,但没有什么可以阻止数据集本身成为所有者。
  • 很高兴知道!我也试试看。
  • 我有 10 个表在不同时间使用,并且在我需要上述属性之前,我的工作方式很好。所以回过头来重构我发现 Martyn 的例子是最简单的,尽管 FPiette 给出了我的方式的确切修复。我将把两者都留在代码中,以便下次再参考它们。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-06-30
  • 1970-01-01
  • 2013-08-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多