I have a class which should contain datafields like TIntegerField, TFloatField, ... In an Init-Function I want to open a dataset to get the right datarecord from DB and put the values to the fields in the classinstance. Because I don't want to write down all the fields of the class I want do this dynamicly with rtti. I wonder how I can create an instance e.g. of a TFLoatfield and copy the FloatField from dataset to classfield. My function finds the floatfiled but I cannot create the Instance and copy the value.
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;
Your comment
is correct, TFields only work when they are associated with a TDataSet; they cannot work in isolation from one because they use the record buffers set up by the dataset to hold the data they operate on.
Wrong. You can create an instance of TFloatField by whatever method you like, e.g.
but I think the point that you have missed is that you can only do this successfully before the dataset is opened. Once the dataset is open it is too late because in the absence of persistent fields, the dataset will create dynamically a set of default fields which only live as long as the dataset is open.
"Persistent" Fields are so called because they are stored in the DFM of the form or DataModule in which they are created using the Fields Editor you can access using the context menu of the dataset in the IDE.
Btw, many people have using Attribute annotations for classes to create customised datasets. One good article on it is here:
http://francois-piette.blogspot.co.uk/2013/01/using-custom-attribute-for-data.html
You might also want to take a look at the Spring4D library, which might save you a lot of work. See e.g. https://spring4d.4delphi.com/docs/develop/Html/index.htm?Spring.Persistence.Core.Base.TDriverResultSetAdapter(T).DataSet.htm as a way into it.