2012-08-06 61 views
3

首先這是我在這裏的第一篇文章,所以我要對不起我的英文不好第一,第二我要抱歉這聽起來是TRttiField - 怎麼投類

以及任何愚蠢的問題,即時通訊試圖寫我自己的特定於MySQL,德爾福和我在這裏工作的團隊, ,但我陷入了一些事情,我不知道該怎麼做,以及我會超過我的班的最終定義。

uses 
     hsORM.Mapping, 
     hsORM.Types; 

    type 
     [ThsORMTableMap('hscad_cadmunicipal')] 
     TMunicipe = class(ThsORMTable) 
     private 
     { Private declarations } 
     [ThsORMColumnPrimaryKeyMap('inscricaomunicipal')] 
     Fid : ThsORMColumnPrimaryKey; 

     [ThsORMColumnNullableMap('idlogradouro', varInteger)] 
     Fidlogradouro : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('idbairro', varInteger)] 
     Fidbairro : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('idestadocivil', varInteger)] 
     Fidestadocivil : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('idnaturezaestab', varInteger)] 
     Fidnaturezaestabelecimento : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('idnaturezajuridica', varInteger)] 
     Fidnaturezajuridica : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('idagencia', varInteger)] 
     Fidagencia : ThsORMColumnNullable; 

     [ThsORMColumnMap('datacadastro')] 
     Fdatacadastro : ThsORMColumnDate; 

     [ThsORMColumnMap('nome')] 
     Fnome : ThsORMColumnString; 

     [ThsORMColumnNullableMap('nomefantasia', varString)] 
     Fnomefantasia : ThsORMColumnNullable; 

     [ThsORMColumnMap('tipopessoa')] 
     Ftipopessoa : ThsORMColumnString; 

     [ThsORMColumnNullableMap('numero', varInteger)] 
     Fnumero : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('complemento', varString)] 
     Fcomplemento : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('observacao', varString)] 
     Fobservacao : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('telefone', varString)] 
     Ftelefone : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('celular', varString)] 
     Fcelular : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('fax', varString)] 
     Ffax : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('sexo', varString)] 
     Fsexo : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('email', varString)] 
     Femail : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('responsavel', varString)] 
     Fresponsavel : ThsORMColumnNullable; 

     [ThsORMColumnNullableMap('contacorrente', varString)] 
     Fcontacorrente : ThsORMColumnNullable; 

     [ThsORMColumnMap('foto')] 
     Ffoto : ThsORMColumnBlob; 

     [ThsORMColumnMap('fornecedor')] 
     Ffornecedor : ThsORMColumnBoolean; 

     [ThsORMColumnMap('tipocredor')] 
     Ftipocredor : ThsORMColumnString; 

     [ThsORMColumnMap('ativo')] 
     Fativo : ThsORMColumnBoolean; 
     public 
     { Public declarations } 
     property id : ThsORMColumnPrimaryKey read Fid write Fid; 
     property idlogradouro : ThsORMColumnNullable read Fidlogradouro write Fidlogradouro; 
     property idbairro : ThsORMColumnNullable read Fidbairro write Fidbairro; 
     property idestadocivil : ThsORMColumnNullable read Fidestadocivil write Fidestadocivil; 
     property idnaturezaestabelecimento : ThsORMColumnNullable read Fidnaturezaestabelecimento write Fidnaturezaestabelecimento; 
     property idnaturezajuridica : ThsORMColumnNullable read Fidnaturezajuridica write Fidnaturezajuridica; 
     property idagencia : ThsORMColumnNullable read Fidagencia write Fidagencia; 
     property datacadastro : ThsORMColumnDate read Fdatacadastro write Fdatacadastro; 
     property nome : ThsORMColumnString read Fnome write Fnome; 
     property nomefantasia : ThsORMColumnNullable read Fnomefantasia write Fnomefantasia; 
     property tipopessoa : ThsORMColumnString read Ftipopessoa write Ftipopessoa; 
     property numero : ThsORMColumnNullable read Fnumero write Fnumero; 
     property complemento : ThsORMColumnNullable read Fcomplemento write Fcomplemento; 
     property observacao : ThsORMColumnNullable read Fobservacao write Fobservacao; 
     property telefone : ThsORMColumnNullable read Ftelefone write Ftelefone; 
     property celular : ThsORMColumnNullable read Fcelular write Fcelular; 
     property fax : ThsORMColumnNullable read Ffax write Ffax; 
     property sexo : ThsORMColumnNullable read Fsexo write Fsexo; 
     property email : ThsORMColumnNullable read Femail write Femail; 
     property responsavel : ThsORMColumnNullable read Fresponsavel write Fresponsavel; 
     property contacorrente : ThsORMColumnNullable read Fcontacorrente write Fcontacorrente; 
     property foto : ThsORMColumnBlob read Ffoto write Ffoto; 
     property fornecedor : ThsORMColumnBoolean read Ffornecedor write Ffornecedor; 
     property tipocredor : ThsORMColumnString read Ftipocredor write Ftipocredor; 
     property ativo : ThsORMColumnBoolean read Fativo write Fativo; 
     end; 

好吧,我爲每個mysql數據類型定義了一個相應的類。以及我想接下來要做的是使用RTTI創建動態的每一個操作系統這個領域。因爲delphi中的類需要被顯式創建,並且我試圖避免這種情況,所以我試圖做的是使用我的類ThsORMTable創建動態的這個列。例如:

ThsORMTable = class 
     private 
     { Private declarations } 
     FTableName: string; 
     procedure InitializeTable(); 
     procedure InitializeColumns(); 
     public 
     { Public declarations } 
     constructor Create(); 
     property TableName : string read FTableName write FTableName; 
     end; 

    { ThsORMTable } 

    {$REGION 'Private'} 

    procedure ThsORMTable.InitializeTable(); 
    var 
     AContext : TRttiContext; 
     AType : TRttiType; 
     AAttribute : TCustomAttribute; 
     AFound : Boolean; 
    begin 
     AContext := TRttiContext.Create(); 
     try 
     AFound := False; 
     AType := AContext.GetType(ClassType); 
     for AAttribute in AType.GetAttributes do 
      if(AAttribute is ThsORMTableMap) then 
      begin 
       FTableName := (AAttribute as ThsORMTableMap).TableName; 
       AFound := True; 
       Break; 
      end; 
     if not(AFound) then raise Exception.Create(ETableNotMapped); 
     finally 
     AContext.Free(); 
     end; 
    end; 

    procedure ThsORMTable.InitializeColumns(); 
    var 
     AContext : TRttiContext; 
     AType : TRttiType; 
     AField : TRttiField; 
     AFound : Boolean; 
    begin 
     AContext := TRttiContext.Create(); 
     try 
     AType := AContext.GetType(ClassType); 
     for AField in AType.GetFields do 
        /********************************************** 
        here i want something like for example 
        if(AField is ThsORMColumnInteger) then 
         begin 
         (AField as ThsORMColumnInteger) := ThsORMColumnInteger.Create(); 
        is this possible? im going to the wrong way? 
         end; 
        **********************************************/ 
     finally 
     AContext.Free(); 
     end; 
    end; 

    {$ENDREGION} 

    {$REGION 'Public'} 

    constructor ThsORMTable.Create(); 
    begin 
     try 
     InitializeTable(); 
     InitializeColumns(); 
     except on Error : Exception do 
     raise ThsORMTableInitialization.Create(Format(ETableInitializationError, [Error.Message])); 
     end; 
    end; 

    {$ENDREGION} 

但我得到一個編譯錯誤,無論如何。 希望你們能幫助我。 thx優勢

更新:對不起,我不清楚,生病再試一次。我試圖做的是通過ThsORMTable,我的祖先類,特別是構造函數方法,初始化每個字段(創建),所以我不需要顯式創建每個繼承自這個祖先的類中的每個字段

+0

什麼是編譯錯誤? – 2012-08-06 20:47:07

+0

[DCC錯誤] hsORM.Types.pas(580):E2015操作符不適用於此操作數類型 – kabstergo 2012-08-06 23:48:11

+0

我的猜測是您混淆了概念,AField是TRTTIField而不是表字段,請檢查Remy Lebeau的注意事項。 – 2012-08-06 23:59:10

回答

4

調用AField is ThsORMColumnIntegerAField as ThsORMColumnInteger將始終失敗,因爲TRttiField不會從ThsORMColumnInteger派生,反之亦然。

目前還不清楚你試圖完成與ThsORMTable類的每個領域。如果你只是想訪問的每個字段的屬性,你並不需要構建一個實際的對象實例來做到這一點,如:

uses 
    ..., TypInfo; 

procedure ThsORMTable.InitializeColumns(); 
var 
    AContext : TRttiContext; 
    AType : TRttiType; 
    AField : TRttiField; 
    AAttribute : TCustomAttribute; 
    AFound : Boolean; 
begin 
    AContext := TRttiContext.Create(); 
    try 
    AType := AContext.GetType(ClassType); 
    for AField in AType.GetFields do 
    begin 
     // TRttiType.TypeData is private so have to use the TypInfo unit directly... 
     TypeData := TypInfo.GetTypeData(AField.FieldType.Handle); 

     if TypeData^.ClassType is ThsORMColumnInteger then 
     begin 
     for AAttribute in AField.GetAttributes do  
     begin 
      if (AAttribute is ThsORMColumnMap) then  
      begin  
      // use (AAttribute as ThsORMColumnMap) as needed ... 
      AFound := True;  
      Break;  
      end; 
     end;  
     if (not AFound) then raise Exception.Create(EColumnNotMapped);  
     end; 
    end; 
    finally 
    AContext.Free(); 
    end; 
end; 

更新:根據您的更新信息,您也許能像做以下,根據您的列類類型如何設置:

type 
    ThsORMColumn = class(...) 
    //... 
    end; 

    ThsORMColumnClass = class of ThsORMColumn; 

    //... 

    ThsORMColumnInteger = class(ThsORMColumn) 
    // ... 
    end; 

    //... 

procedure ThsORMTable.InitializeColumns();  
var  
    AContext : TRttiContext;  
    AType : TRttiType;  
    AField : TRttiField;  
    AAttribute : TCustomAttribute; 
    AObj : ThsORMColumn; 
begin  
    AContext := TRttiContext.Create();  
    try  
    AType := AContext.GetType(ClassType);  
    for AField in AType.GetFields do  
    begin 
     if AField.FieldType.TypeKind = tkClass then 
     begin 
     // TRttiType.TypeData is private so have to use the TypInfo unit directly... 
     TypeData := TypInfo.GetTypeData(AField.FieldType.Handle); 
     if (not TypeData^.ClassType.InheritsFrom(ThsORMColumn)) then 
      raise Exception.Create(...);   
     AObj := ThsORMColumnClass(TypeData^.ClassType).Create();   
     AField.SetValue(Self, Obj); 
     end; 
    end; 
    finally  
    AContext.Free();  
    end;  
end;  

這種方法的好處是,你在技術上不必在爲這一切來標記屬性的領域工作,雖然我懷疑你仍然想爲其他目的做到這一點。

+0

對不起,我不清楚,生病再試一次。我試圖做的是通過ThsORMTable,我的祖先類,特別是構造函數方法,初始化每個字段(創建),所以我不需要顯式創建每個從這個祖先繼承的類中的每個字段 – kabstergo 2012-08-06 23:54:46

+0

這正是我所尋找的,這件作品像一個魅力,thx爲你的幫助伴侶 – kabstergo 2012-08-07 11:52:38

相關問題