delphifiredac

Delphi FireDAC handle new detail records in CachedUpdateMode


I have in MariaDB normalized tables named

L1MasterTable with columns

L2AddressTable with columns

L3AddressDetailTable with columns

Tables are in relation

In Delphi I have 3 very simple FDQueries that manage tables above

FDQuery1.Connection:=DataModule1.c; 
FDQuery1.SQL.Clear;
FDQuery1.SQL.Text:='SELECT id, name, surname, email from L1MasterTable';
DataSource1.DataSet:=FDQuery1;
FDQuery1.FetchOptions.Mode := fmAll;
FDQuery1.CachedUpdates:=true; //I am working in CachedUpdatesMode for all tables
DataModule1.FDQueryOpen(FDQuery1,'FDQuery1 initDB');

FDQuery2.Connection:=DataModule1.c; //detail ISU a grid vpravo
FDQuery2.CachedUpdates:=true;
FDQuery2.SQL.Clear;
FDQuery2.SQL.Text:='SELECT id, pid, City, Street, Country from L2AddressTable order by pid'; 
FDQuery2.FetchOptions.Mode := fmAll;
FDQuery2.FetchOptions.DetailCascade:=true; //needed to be treated as Master/Detail mode
DataSource2.DataSet:=FDQuery2;
DataModule1.FDQueryOpen(FDQuery2,'FDQuery2 initDB');

FDQuery3.SQL.Clear;
FDQuery3.Connection:=DataModule1.c;
FDQuery3.CachedUpdates:=true;
FDQuery3.SQL.Text:='SELECT id, pid, addressdetail from L3AddressDetailTable order by pid'; 
DataSource3.DataSet:=FDQuery3;
FDQuery3.FetchOptions.DetailCascade:=true;
DataModule1.FDQueryOpen(FDQuery3,'FDQuery3 initDB');

My question is: How do i handle cases when I create for example one record in L1MasterTable and also detailed records in L2MasterTable and L3MasterTable. In CachedUpdateMode has new record id <0. For example -1, -2, ... When I want to add new record in L2MasterTable I do not know how to handle nonexisting id from parent table.

What is best practice how to handle this situation in Delphi using Firedac?

I must mention that my MariaDB works in MyISAM and i cant set relation directly in database.


Solution

  • All requested functionality is provided by FireDAC's component named TFDSchemaAdapter. This component handles all id assignments.

    Delphi documentantion: https://docwiki.embarcadero.com/Libraries/Sydney/en/FireDAC.Comp.Client.TFDSchemaAdapter

    Examples: https://docwiki.embarcadero.com/CodeExamples/Athens/en/FireDAC.SchemaAdapterMemTable_Sample

    Or examples on GitHub: https://github.com/Embarcadero/RADStudio12Demos/tree/main/Object%20Pascal/Database/FireDAC/Samples/Comp%20Layer/TFDQuery/CachedUpdates/Centralized

    Very simple snippet showing data saving do db, once everything is set according manual above:

     if FDSchemaAdapter1.UpdatesPending then
      begin
        FDSchemaAdapter1.ApplyUpdates; //applies correct IDs to all binded queries
        FDQuery1.CommitUpdates;
        FDQuery2.CommitUpdates;
        FDQuery3.CommitUpdates;
      end;