2012-11-12 2 views
3

un coup d'oeil le code suivant:Obtenir la taille Enum et nom comme paramètre générique

uses 
    TypInfo, Dialogs, Classes, Generics.Collections, ADODB, DB, SysUtils; 

type 
    TTable_1 = (ID, FName, LName, FatherName); 

type 
    TBaseTable<TableType> = class(TADOQuery) 
    public 
    constructor Create(AOwner: TComponent); Override; 
    procedure Select(DS: TDataSource); 
    end; 

implementation 

{ TBaseTable<TableType> } 

constructor TBaseTable<TableType>.Create(AOwner: TComponent); 
begin 
    inherited; 
    Self.Connection := DataModule3.ADOConnection1; 
    Self.Connection.Connected := True; 
end; 

procedure TBaseTable<TableType>.Select(DS: TDataSource); 
var 
    Query: string; 
    EnumIndex: Byte; 
begin 
    EnumIndex := 0; 
    Query := 'SELECT '; 
    while (GetEnumName(TypeInfo(TableType), EnumIndex) <> UnitName) do 
    begin 
    Query := Query + GetEnumName(TypeInfo(TableType), EnumIndex) + ','; 
    Inc(EnumIndex); 
    end; 
    Query := Copy(Query, 0, Length(Query) - 1); 
    Query := Query + ' FROM Table_1'; 
    Close; 
    SQL.Text := Query; 
    Open; 
    DS.DataSet := Self; 
end; 

Je l'utilise aime:

var 
    Test: TBaseTable<TTable_1>; 
begin 
    Test := TBaseTable<TTable_1>.Create(Self); 
    Test.Select(DataSource1); 
end; 

Comme vous pouvez le voir, je vous écris au nom de la table Dans la requête en tant que chaîne statique ('Table_1'), je veux obtenir le nom enum et le passer à l'instruction select en tant que nom de table pour rendre le code plus utilisable. Une autre question est de savoir comment obtenir la taille enum passé pour obtenir les noms de champs, comme vous pouvez le voir actuellement, je compare le nom enum actuel avec le nom de l'unité, c'est une mauvaise idée, quelqu'un peut m'aider?

Au moins, je veux développer une classe, écrire un Enum pour chaque table dans ma base de données et le transmettre à ma classe et les méthodes de ma classe utiliser pour sélectionner, insérer, modifier, etc

Je veux écrire un micro ORM pour mon usage personnel.

Merci.

Répondre

6

Vous pouvez utiliser la nouvelle unité de System.RTTI:

function TBaseTable<TableType>.Select: string; 
var 
    EnumIndex: Byte; 
    Context: TRttiContext; 
    TableTypeRtti: TRttiEnumerationType; 
begin 
    Context := TRttiContext.Create; 
    try 
    TableTypeRtti := Context.GetType(TypeInfo(TableType)) as TRttiEnumerationType; 
    Result := 'SELECT '; 
    for EnumIndex := TableTypeRtti.MinValue to TableTypeRtti.MaxValue do begin 
     Result := Result + GetEnumName(TypeInfo(TableType), EnumIndex) + ','; 
    end; 
    Result := Copy(Result, 0, Length(Result) - 1); 
    Result := Result + ' FROM ' + TableTypeRtti.Name; 
    finally 
    Context.Free; 
    end; 
end; 
+1

+1. Mais il est dommage que 'TRttiEnumerationType.GetName ' n'a pas encore été rendu public (http://qc.embarcadero.com/wc/qcmain.aspx?d=90339 –

Questions connexes