我有一个类应包含数据字段,如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;
答案 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作为一种方式。