delphitclientdataset

How to set TClientDataSet field names and displayName


Delphi 10.3

I'm trying to setup a TClientDataSet to use in my tests, but after adding the fields the Name and DisplayText properties are empty, and the DisplayLabel property has the FieldName property.

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;

Just a quick test:

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;

The Assert.AreEqual(3, DS.Fields.Count); passes but all Name and DisplayText properties fail.

Field[0] logs this

Field 0 DisplayLabel = id

Field 0 Name =

Field 0 DisplayText =

Adding the field property assignments into the test everything passes, so the fields are present.

Does anyone know why the field properties are not set in the Dataset creation? The fields are there. The assigned name of the DataSet is fine also.

Thanks in advance

Gary


Solution

  • You have to assign lcPersistent to the LifeCycle property like this:

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

    And of course do the same with all fields.

    Warning: The field property name must be unique because it is used as component name which must be unique. You should probably construct it with dataset name combined.