You are not logged in.
Pages: 1
I want to compare two sets of files. A file (filename) may appear in just one set or in both of them. And, in this case, they may have the same size an modification date or not.
So, for every single file I have the following structure:
TSQLMyFileInfo = class(TSQLRecord)
private
FMyFileDate: TDateTime;
FMyFileSize: Int64;
procedure SetMyFileDate(const Value: TDateTime);
procedure SetMyFileSize(const Value: Int64);
published
property MyFileDate: TDateTime read FMyFileDate write SetMyFileDate;
property MyFileSize: Int64 read FMyFileSize write SetMyFileSize;
end;
TSQLMyFile = class(TSQLRecord)
private
FSecondOne: TSQLMyFileInfo;
FFirstOne: TSQLMyFileInfo;
FMyFileName: RawUTF8;
FMyFileInfo: TSQLMyFileInfo;
procedure SetFirstOne(const Value: TSQLMyFileInfo);
procedure SetMyFileName(const Value: RawUTF8);
procedure SetSecondOne(const Value: TSQLMyFileInfo);
procedure SetMyFileInfo(const Value: TSQLMyFileInfo);
published
property MyFileName: RawUTF8 read FMyFileName write SetMyFileName;
property FirstOne: TSQLMyFileInfo read FFirstOne write SetFirstOne;
property SecondOne: TSQLMyFileInfo read FSecondOne write SetSecondOne;
property MyFileInfo: TSQLMyFileInfo read FMyFileInfo write SetMyFileInfo;
end;
To save the "MyFile" object I do the following, after filling its properties:
MyDataBase.Add(MyFile.FirstOne, True);
MyDataBase.Add(MyFile.SecondOne, True);
MyDataBase.Add(MyFile, True);
But when I look into the table ("MyFile") I see it has saved the address of the objects (FirstOne, SecondOne) instead of their ids.
Could someone please tell me what am I doing wrong?
Thanks in advance
Offline
MyFile.FirstOne and MyFile.SecondOne should be IDs, so you can't use those properties as TSQLMyFileInfo instances.
As stated by the documentation, TSQLRecord published properties do not contain an instance of the TSQLRecord class. It will instead contain pointer(RowID), and will be stored as an INTEGER in the database.
So do not use directly such published properties, like a regular class instance: you'll have an access violation.
When creating such records, use temporary instances for each detail object, as such:
var One, Two: TSQLMyFileInfo;
MyFile: TSQLMyFile;
begin
One := TSQLMyFileInfo.Create;
Two := TSQLMyFileInfo.Create;
MyFile := TSQLMyFile.Create;
try
One.MyFileDate := ....
One.MyFileSize := ...
MyFile.FirstOne := TSQLMyFileInfo(MyDataBase.Add(One,True)); // add One and store ID in MyFile.FirstOne
Two.MyFileDate := ....
Two.MyFileSize := ...
MyFile.SecondOne:= TSQLMyFileInfo(MyDataBase.Add(Two,True)); // add Two and store ID in MyFile.SecondOne
MyDataBase.Add(MyFile);
finally
MyFile.Free;
Two.Free;
One.Free;
end;
end;
When accessing the detail objects, don't access directly to FirstOne or SecondOne properties (there are not class instances, but IDs), then use instead the TSQLRecord. Create(aClient: TSQLRest; aPublishedRecord: TSQLRecord: ForUpdate: boolean=false) overloaded constructor, as such:
var One: TSQLMyFileInfo;
MyFile: TSQLMyFile;
begin
MyFile := TSQLMyFile.Create(Client,aMyFileID);
try
// here MyFile.FirstOne.MyFileDate will trigger an access violation
One := TSQLMyFileInfo.Create(Client,MyFile.FirstOne);
try
// here you can access One.MyFileDate or One.MyFileSize
finally
One.Free;
end;
finally
MyFile.Free;
end;
end;
Or with a with statement:
with TSQLMyFileInfo.Create(Client,MyFile.FirstOne) do
try
// here you can access MyFileDate or MyFileSize
finally
Free;
end;
Up to now, there is no Lazy Loading feature in our ORM, for the TSQLRecord classes. This could sound like a limitation, but it allows to manage exactly the data to be retrieved from the server in your code, and maintain bandwidth and memory use as low as possible. Lazy loading is available by defining TPersistent, TCollection or dynamic arrays in the TSQLRecord published fields: as we'll state in the following paragraphs, the content of those fields are stored and retrieved together with the other simple published fields (e.g. integer, RawUTF8...).
The only case when some class instance are automatically created is for TSQLRecordMany published properties (see the documentation).
Offline
Thanks a lot for answering so quickly.
I had already read "TSQLRecord published properties do not contain an instance of the TSQLRecord class" in the SAD but I did not fully understand it.
I am going to try it right now.
Offline
I've updated the documentation with my answer above.
It was not clear enough.
In fact, the answer above is a copy & paste of the updated paragraph of the documentation.
Thanks for the feedback and interest.
Offline
Pages: 1