Cant figure out association syntax

I have 2 objects, Applications and DataPaths. An application can have multiple datapaths. I have the following code

  var application := database.FindApplication.Where(Linq[Dic.Applications.name.PropName] = req.IniData['application']).UniqueResult;
  Assert(Assigned(application), format('Unknown application "%s"', [req.IniData['application']]));

  var datapath := database.FindDataPath.Where((Linq[Dic.Datapaths.path.PropName] = req.IniData['path']) and (Linq[Dic.Datapaths.applicationId.PropName] = application.id)).UniqueResult;
  if not Assigned(datapath) then
  begin
    datapath := TDataPaths.Create;
    datapath.path := req.IniData['path'];
    database.Save(datapath);
  end;

The FindDataPath and FindApplication are as follows

function TDatabase.FindApplication: TCriteria<TApplications>;
begin
  result := FManager.Find<TApplications>;
end;

I'm struggling to see how I should code the line that starts with "var datapath :=" specifically the last condition that should select the object with the already located application.

The 2 classes in question were generated by DataModeler as below

  [Entity]
  [Table('Applications')]
  [Id('Fid', TIdGenerator.IdentityOrSequence)]
  TApplications = class
  private
    [Column('id', [TColumnProp.Required, TColumnProp.NoInsert, TColumnProp.NoUpdate])]
    Fid: Integer;
    
    [Column('name', [TColumnProp.Required], 15)]
    Fname: string;
    
    [Column('maxLicensedConnections', [TColumnProp.Required])]
    FmaxLicensedConnections: Integer;
    
    [ManyValuedAssociation([TAssociationProp.Lazy, TAssociationProp.Required], [TCascadeType.SaveUpdate, TCascadeType.Merge], 'FapplicationId')]
    FDataPathsList: Proxy<TList<TDataPaths>>;
    function GetDataPathsList: TList<TDataPaths>;
  public
    constructor Create;
    destructor Destroy; override;
    property id: Integer read Fid write Fid;
    property name: string read Fname write Fname;
    property maxLicensedConnections: Integer read FmaxLicensedConnections write FmaxLicensedConnections;
    property DataPathsList: TList<TDataPaths> read GetDataPathsList;
  end;
  
  [Entity]
  [Table('DataPaths')]
  [Id('Fid', TIdGenerator.IdentityOrSequence)]
  TDataPaths = class
  private
    [Column('id', [TColumnProp.Required, TColumnProp.NoInsert, TColumnProp.NoUpdate])]
    Fid: Integer;
    
    [Column('path', [TColumnProp.Required], 80)]
    Fpath: string;
    
    [Association([TAssociationProp.Lazy, TAssociationProp.Required], CascadeTypeAll - [TCascadeType.Remove])]
    [JoinColumn('applicationId', [TColumnProp.Required], 'id')]
    FapplicationId: Proxy<TApplications>;
    
    [ManyValuedAssociation([TAssociationProp.Lazy, TAssociationProp.Required], [TCascadeType.SaveUpdate, TCascadeType.Merge], 'FdataPathId')]
    FFileKeysList: Proxy<TList<TFileKeys>>;
    
    [ManyValuedAssociation([TAssociationProp.Lazy, TAssociationProp.Required], [TCascadeType.SaveUpdate, TCascadeType.Merge], 'FdataPathId')]
    FWorkstationsList: Proxy<TList<TWorkstations>>;
    function GetapplicationId: TApplications;
    procedure SetapplicationId(const Value: TApplications);
    function GetFileKeysList: TList<TFileKeys>;
    function GetWorkstationsList: TList<TWorkstations>;
  public
    constructor Create;
    destructor Destroy; override;
    property id: Integer read Fid write Fid;
    property path: string read Fpath write Fpath;
    property applicationId: TApplications read GetapplicationId write SetapplicationId;
    property FileKeysList: TList<TFileKeys> read GetFileKeysList;
    property WorkstationsList: TList<TWorkstations> read GetWorkstationsList;
  end;

Do you have any suggestions on where I'm going wrong ?

It should be something more or less like this:

var datapath := database
  .FindDataPath
  .CreateAlias(Dic.Datapaths.applicationId.AssociationName, 'app')
  .Where((Linq[Dic.Datapaths.path.PropName] = req.IniData['path']) and
    (Linq['app.' + Dic.Applications.id.PropName] = application.id))
  .UniqueResult;

Thanks for that Wagner. It makes sense, but Dic.Datapaths.applicationId.PropName doesn't exist. It has Dic.Datapaths.applicationId.AssociationName. Is that able to be used instead of PropName or (as I suspect) the syntax different ?

1 Like

Actually, further checking shows that the AssociationName has the property name in it. I'll try that and see how I go.

1 Like

All seems to be working with the AssociationName. Thanks Wagner

1 Like

This topic was automatically closed 60 minutes after the last reply. New replies are no longer allowed.