首先,这是我在这里的第一篇文章,所以我想先抱歉我的英语不好,其次我想对任何听起来可能听起来很愚蠢的问题感到抱歉
好吧,我正在尝试为MySQL,Delphi和我在这里工作的团队编写我自己的ORM, 但是我陷入了一些我不知道该怎么做的事情,我将在我班级的最终定义之上发布。
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,我的祖先类,特别是在构造函数方法上,初始化每个字段(创建),所以我不需要在从祖先继承的每个类中显式创建每个字段< / p>
答案 0 :(得分:4)
调用AField is ThsORMColumnInteger
和AField 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;
这种方法的好处在于,从技术上讲,您根本不需要使用属性标记字段才能使其工作,但我怀疑您仍然希望将其用于其他目的。