Bonjour,

Je cherche actuellement comment organiser proprement mon code pour intéragir avec ma base de données.
Pour cela je suis parti sur 2 objets simples, mais je prévois d'avoir par la suite des objets beaucoup plus complexes.
J'ai les 2 objets suivants :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
 
  type
    TChange = class(TObjectFromDB)
    strict private
      FDeviseRef: TDevise;
      FDevise   : TDevise;
      FDebut    : TDateTime;
      FRate     : Extended;
    strict protected
      function GetTableNom: String; override;
      procedure LoadQuery(qry: TSQLQuery); override;
    public
      constructor Create;
      destructor Destroy; override;
      property DeviseRef: TDevise read FDeviseRef;
      property Devise   : TDevise read FDevise;
      property Debut    : TDateTime read FDebut;
      property Rate     : Extended read FRate;
    end;
 
implementation
 
{ TChange }
 
constructor TChange.Create;
begin
  FDevise    := nil;
  FDeviseRef := nil;
end;
 
destructor tchange.destroy;
begin
  if (Assigned(FDeviseRef)) then FreeAndNil(FDeviseRef);
  if (Assigned(FDevise))    then FreeAndNil(FDevise);
end;
 
function TChange.GetTableNom: String;
begin
  Result := TBL_CHANGES;
end;
 
procedure TChange.LoadQuery(qry: TSQLQuery);
begin
  FId        := qry.FieldByName('id'   ).AsInteger;
  FNom       := qry.FieldByName('nom'  ).AsString;
  FDebut     := qry.FieldByName('since').AsDateTime;
  FRate      := qry.FieldByName('taux' ).AsFloat;
 
  FDeviseRef := TDevise.Create;
  FDevise    := TDevise.Create;
  FDeviseRef.LoadFor(qry.FieldByName('devise_ref').AsInteger);
  FDevise.LoadFor(qry.FieldByName('devise').AsInteger);
end;
Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
 
  type
    TDevise = class(TObjectCodeFromDB)
    private
      FSymbole  : String;
      FNbDecimal: Integer;
    protected
      procedure LoadQuery(qry: TSQLQuery); override;
    function GetTableNom: String; override;
    public
      property Symbole    : String  read FSymbole;
      property NbDecimales: Integer read FNbDecimal;
    end;
 
implementation
 
uses
  datas;
 
{ TDevise }
 
function TDevise.GetTableNom: String;
begin
  Result := TBL_DEVISES;
end;
 
procedure TDevise.LoadQuery(qry: TSQLQuery);
begin
  FId        := qry.FieldByName('id'          ).AsInteger;
  FCode      := qry.FieldByName('code'        ).AsString;
  FNom       := qry.FieldByName('nom'         ).AsString;
  FSymbole   := qry.FieldByName('symbole'     ).AsString;
  FNbDecimal := qry.FieldByName('nb_decimales').AsInteger;
end;

Ces 2 objets héritent de TObjectFromDB dans lequel se trouve la fonction suivante :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
procedure TObjectFromDB.LoadFor(id: Integer);
var qry: TSQLQuery;
begin
  qry := CreateQuery(GetQueryStr);
  qry.ParamByName('ID').AsInteger := id;
  try
    qry.Open;
 
    if (not qry.EOF) then LoadQuery(qry);
  finally
    FreeNilDataSet(qry);
  end;
end;

Ce code fonctionne très bien, voici par exemple un petit test :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
procedure TFrmMain.FormCreate(Sender: TObject);
var
  d: TDevise;
  c: TChange;
begin
  d := TDevise.Create;
  d.LoadFor(1);
  c := TChange.Create;
  c.LoadFor(1);
 
  ShowMessage(c.Nom);
  ShowMessage(d.Nom);
 
  FreeAndNil(c);
  FreeAndNil(d);
end;

Le problème qui apparait déjà est que pour charger un TChange, je dois faire 3 requêtes.
1 sur la table "change" puis 2 autres pour charger chacun des TDevise qu'il utilise.

Comment pensez-vous qu'il faille faire pour instancier proprement mes différents objets ?
Comment organiser mon code ?

Merci d'avance de vos réponses et conseils.