使用rtti创建类字段的实例

时间:2017-04-06 08:56:23

标签: delphi object rtti datafield

我有一个类应包含数据字段,如TIntegerField,TFloatField,...在Init-Function中我想打开一个数据集,从DB获取正确的datarecord,并将值放到classinstance中的字段中。因为我不想写下我想要的所有课程的字段,所以我要用rtti动态地做这个。我想知道如何创建一个实例,例如一个TFLoatfield并将FloatField从数据集复制到classfield。我的函数找到了floatfiled但我无法创建实例并复制该值。

var
  rttiContext: TRttiContext;
  rttiType: TRttiType;
  attribute: TCustomAttribute;
  rttiField: TRttiField;
begin
  myQuery.Close;
  myQuery.SQL.Clear;
  myQuery.SQL.Add('SELECT * FROM prices');
  myQuery.SQL.Add('WHERE ID=' + IntToStr(FID));
  myQuery.Open();
  try
    rttiContext := TRttiContext.Create;
    try
      rttiType := rttiContext.GetType(TPrice);
      for rttiField in rttiType.GetFields do
      begin
        if rttiField.FieldType.ToString = 'TFloatField' then
        begin
          // create Instance of Floatfield does not work!
          if not assigned(TFloatField(rttiType.GetField(rttiField.Name))) then
            TFloatField(rttiType.GetField(rttiField.Name)).Create(nil);
          // Copy Floatfield from dataset to classfield does not work!
          TFloatField(rttiType.GetField(rttiField.Name)).Value := tmpQuery.FieldByName(rttiField.Name).Value;
        end;
      end;
    finally
      rttiContext.Free;
    end
  finally
    myQuery.Close;
  end;
end; 

1 个答案:

答案 0 :(得分:0)

您的评论

  

将Floatfield从数据集复制到classfield不起作用!

是正确的,TField仅在与TDataSet关联时才起作用;他们 不能单独工作,因为它们使用由设置的记录缓冲区 用于保存其操作数据的数据集。

  

创建Floatfield的实例不起作用!

错误。您可以通过您喜欢的任何方法创建TFloatField的实例,例如。

var FloatField : TFloatField;

  FloatField := TFloatField.Create(Self);  //  self being e.g. TForm1 or DataModule1
  FloatField.FieldName := 'AFloatField';
  FloatField.FieldKind := fkData;
FloatField.DataSet := myQuery;
  [etc]

但我认为您错过的一点是,您可以 成功完成此操作 之前打开数据集。一旦数据集打开,就太晚了,因为在 如果没有持久字段,数据集将动态创建一组默认值 只有数据集打开才能生效的字段。

"持久性"字段之所以被称为是因为它们存储在表单的DFM中,或者使用可以使用IDE中数据集的上下文菜单访问的字段编辑器创建它们的DataModule。

顺便说一句,很多人都使用属性注释来创建自定义数据集。关于它的一篇好文章就在这里:

http://francois-piette.blogspot.co.uk/2013/01/using-custom-attribute-for-data.html

您可能还想看一下Spring4D库,这可能会为您节省大量的工作。参见例如https://spring4d.4delphi.com/docs/develop/Html/index.htm?Spring.Persistence.Core.Base.TDriverResultSetAdapter(T).DataSet.htm作为一种方式。