Wagner,
I tried to change my code to the following (replaced irrelevant code with ...):
I have the following TEntity structure:
TSchematic
- TSettings (1-1)
- TFormationList (1-M) -> TFormation
- TBarrierList (1-M) -> TBarrier
- TSectionList (1-M) -> TSection, each TSection has the following proxies:
- TExternalList (1-M) -> TExternal
- TInternalList (1-M) -> TInternal
- TAncillaryList (1-M) -> TAncillary
I changed the code to use the TXDataJsonServerSerializer:
var
LFileName, LStrJson: string;
LCurID: TGUID;
LSchematic: TSchematic;
LSerializer: TXDataJsonServerSerializer;
LJsonFile: TextFile;
ii, jj: Integer;
begin
...
if sdExport.Execute then
begin
LFileName := sdExport.FileName;
LCurID := adsSchematicsView.Current<TSchematicView>.Id; // DataSet displaying a list obtained from a View (Model 'Views').
LSchematic := omDatabase.ObjManager.Find<TSchematic>(LCurID); // Retrieve full TSchematic entity (Model 'Database').
if assigned(LSchematic) then
begin
// Dummy reads to force loading proxies
ii := LSchematic.Settings.Casing_Line; // Integer property of TSettings
ii := LSchematic.FormationList.Count;
ii := LSchematic.BarrierList.Count;
for ii := 0 to LSchematic.SectionList.Count - 1 do
begin
jj := LSchematic.SectionList[ii].ExternalList.Count;
jj := LSchematic.SectionList[ii].InternalList.Count;
jj := LSchematic.SectionList[ii].AncillaryList.Count;
end;
LSerializer := TXDataJsonServerSerializer.Create(TXDataAureliusModel.Default);
LStrJson := LSerializer.Write(LSchematic);
try
AssignFile(LJsonFile, LFileName);
Rewrite(LJsonFile);
WriteLn(LJsonFile, LStrJson);
CloseFile(LJsonFile);
messageSkin('Schematic successfully exported.', mtInformation, [mbOK], 0);
finally
LSerializer.Free;
end;
end
else
raise Exception.Create('Unable to obtain Schematic for export!');
end;
Using this code, I get an exception: "Could not find JSON converter for type "Proxy<uSD_WellSchematicEntitites.TSettings>""
TSettings is the first proxy in the main entity class I am trying to export (1-1 relation).
Previously, I used:
LSerializer := TDataSnapJsonSerializer.Create;
LJsonValue := LSerializer.ToJson(LSchematic);
Writing LJSonValue.ToString to the TextFile worked fine (albeit that the resulting text file was not nicely structure; it was just a single string).
On the import side, I have tried to use the TXDataJsonClientDeserializer but I get nowhere either. The constructor requires a IJsonSolver as parameter, but I cannot find any documentation on this. I tried a nil value, but this gets me nowhere either:
var
LFileName, LStrJson, LStrTemp: string;
LJsonFile: TextFile;
LJsonValue: TJsonValue;
LDeserializer: TXDataJsonClientDeserializer;
LSchematic: TSchematic;
LSchematicView: TSchematicView;
begin
...
if odImport.Execute then
begin
LFileName := odImport.FileName;
// Read JSON file
LStrJson := '';
AssignFile(LJsonFile, LFileName);
Reset(LJsonFile);
while not eof(LJsonFile) do
begin
ReadLn(LJsonFile, LStrTemp);
LStrJson := LStrJson + LStrTemp;
end;
CloseFile(LJsonFile);
LJsonValue := TJSONObject.ParseJSONValue(LStrJson);
LDeserializer := TXDataJsonClientDeserializer.Create(TXDataAureliusModel.Default, nil); // nil acceptable????
try
LSchematic := LDeserializer.Read<TSchematic>(LJsonValue.ToJson);
omDatabase.ObjManager.SaveOrUpdate(LSchematic);
// Add imported schematic to view data...
LSchematicView := omView.ObjManager.Find<TSchematicView>(LSchematic.Id);
FSchematicList.Add(LSchematicView);
adsSchematicsView.Refresh;
finally
// LSchematic.Free; // Should not be required. After SaveOrUpdate, ObjectManager owns the entity...
LDeserializer.Free;
LJsonValue.Free;
end;
end;
With this code I get an exception: "Property "$type" does not refer to a know property in type "uSD_WellSchematicEntitites.TSchematic".
Using the DataSnapDeserializer I have the following:
LJsonValue := TJSONObject.ParseJSONValue(LStrJson);
LDeserializer := TDataSnapJsonDeserializer.Create;
try
LSchematic := LDeserializer.FromJson<TSchematic>(LJsonValue); // Transient object, must be destroyed!
omDatabase.ObjManager.SaveOrUpdate(LSchematic);
// Add imported schematic to view data...
LSchematicView := omView.ObjManager.Find<TSchematicView>(LSchematic.Id);
FSchematicList.Add(LSchematicView);
adsSchematicsView.Refresh;
showMessage('Import succeeded');
finally
// LSchematic.Free;
LDeserializer.Free;
LJsonValue.Free;
Screen.Cursor := crDefault;
end;
end;
This code "works" (showMessage executed) without an exception occuring but the entity (not even the top-level TSchematic) is imported. As a result, the View data shows a blank record (understandable, as failure to retrieve LSchematicView (nil) is adding a nil object to FSchematicList).
In essence I am trying to write a TEntity to a file (JSon format) and later read it (JSon format) to re-create a TEntity to save (or update) in the database.
Surely this is not that complex? Hopefully you can tell me where I am going wrong.
PS: If you give any example code, can you please include the uses clause? This will save a lot of time searching for the right units. ;-)
Regards,
Mark