![]() |
RTTI und ShortString in records...
Ich versuche gerade, records in einer Liste durch RTTI in Datenbankfelder und -register zu verwandeln. Dazu will ich die genutzten records dynamisch über RTTI auslesen, ein Memory-Dataset nutzen um die Felder anzulegen und dann das Dataset mit den Daten aus den records füllen.
Jetzt habe ich das Problem, dass im Falle von ShortStrings in den records kein FieldType existiert, das Feld ist da immer nil... Bei der Ausgabe die man, dass zwar das Feld MiddleName erkannt wird, aber keinen FieldType zugewisen bekommt.
Code:
Frage : Wie komme ich an den Typ (ShortString) und dessen Länge (in dem Fall 125) ran ?
program Project4;
{$APPTYPE CONSOLE} {$R *.res} uses System.SysUtils, System.Rtti, System.TypInfo, System.Generics.Collections; type TSampleRec = packed record Id: Integer; FirstName: String; LastName: String; MiddleName: String[125]; Sex: Char; IsActive: Boolean; end; procedure RTTI_AnalyzeRecord(ATypeInfo: Pointer); var ctx : TRttiContext; lType : TRttiType; lField : TRttiField; begin ctx := TRttiContext.Create; if not Assigned(ATypeInfo) then exit; lType:=ctx.GetType(ATypeInfo); if not Assigned(lType) then exit; for lField in lType.GetFields do begin if Not Assigned(lField.FieldType) then begin WriteLn(Format('%-20s:%s;',[lField.Name,'Unknown'])); end else WriteLn(Format('%-20s:%s;',[lField.Name,lField.FieldType.Name])); end; end; begin try RTTI_AnalyzeRecord(TypeInfo(TSampleRec)); Readln; except on E: Exception do Writeln(E.ClassName, ': ', E.Message); end; end. |
AW: RTTI und ShortString in records...
Zitat:
|
AW: RTTI und ShortString in records...
Zitat:
Delphi-Quellcode:
Bis bald...
type
TString125 = String[125]; TSampleRec = packed record Id: Integer; FirstName: String; LastName: String; MiddleName: TString125; Sex: Char; IsActive: Boolean; end; var rttiType: TRttiType := TRttiContext.Create.GetType(TypeInfo(TSampleRec)); if rttiType <> Nil then begin var recFieldType: TRttiType; for var field: TRttiField in rttiType.GetFields do begin recFieldType := field.FieldType; if (recFieldType is TRttiStringType) and (TRttiStringType(recFieldType).StringKind = skShortString) then begin ShowMessage((TRttiStringType(recFieldType).TypeSize - 1).ToString); end; end; end; Thomas |
AW: RTTI und ShortString in records...
Zitat:
![]()
Delphi-Quellcode:
Bis bald...
uses
mormot.core.base, mormot.core.data, mormot.core.json, mormot.core.text, mormot.orm.base, mormot.db.core, mormot.ui.rad.json; type PSampleRec = ^TSampleRec; TSampleRec = packed record Id: Integer; FirstName: String; LastName: String; MiddleName: String[125]; Sex: Char; IsActive: Boolean; end; TSampleRecDynArray = array of TSampleRec; ... private class procedure TSampleRecWriter(pmWriter: TJsonWriter; pmData: Pointer; pmOptions: TTextWriterWriteObjectOptions); class procedure ...TSampleRecWriter(pmWriter: TJsonWriter; pmData: Pointer; pmOptions: TTextWriterWriteObjectOptions); var rec: PSampleRec absolute pmData; begin pmWriter.AddJsonEscape(['ID', rec.Id, 'FirstName', rec.FirstName, 'LastName', rec.LastName, 'MiddleName', rec.MiddleName, 'Sex', rec.Sex, 'IsActive', rec.IsActive]); end; procedure ...TestOrmTableDataSet; var dataArr: TSampleRecDynArray; begin SetLength(dataArr, 2); dataArr[0].Id := 1; dataArr[0].FirstName := 'Klaus'; dataArr[0].LastName := 'Meier'; dataArr[0].MiddleName := 'Peter'; dataArr[0].Sex := 'M'; dataArr[0].IsActive := True; dataArr[1].Id := 2; dataArr[1].FirstName := 'Carmen'; dataArr[1].LastName := 'Schmitt'; dataArr[1].MiddleName := 'Maria'; dataArr[1].Sex := 'F'; dataArr[1].IsActive := True; var content: RawByteString := DynArraySaveJson(dataArr, TypeInfo(TSampleRecDynArray)); var dataSet: TOrmTableDataSet := JsonToDataSet(Self, content); if dataSet <> Nil then begin dataSet.Last; ShowMessage(Format('RowCount: %d, ID: %d, FirstName: %s, LastName: %s, MiddleName: %s', [ dataSet.RecordCount, dataSet.FieldByName('ID').AsInteger, dataSet.FieldByName('FirstName').AsString, dataSet.FieldByName('LastName').AsString, dataSet.FieldByName('MiddleName').AsString])); dataSet.Free; end; initialization TRttiJson.RegisterCustomSerializer(TypeInfo(TSampleRec), Nil, ...TSampleRecWriter); Thomas |
AW: RTTI und ShortString in records...
Also das Geheimrezept ist also, dass man in Records keine String[125] direkt nutzt, sondern die als Typ z.B. TString125 anlegt und diesen typ dann im Record nutzt...
Vielen Dank, hätte ich jetzt so nicht erwartet, aber naja.. Zitat:
|
AW: RTTI und ShortString in records...
Zitat:
Delphi-Quellcode:
Bis bald...
uses
System.Rtti, System.TypInfo, mormot.core.base, mormot.core.rtti; type TString125 = String[125]; TSampleRec = packed record Id: Integer; FirstName: String; LastName: String; MiddleName: TString125; Sex: Char; IsActive: Boolean; end; begin ShowMessage(GetTypeName(TypeInfo(TString125))); ShowMessage(GetTypeData(TypeInfo(TString125)).MaxLength.ToString); ShowMessage(GetTypeName(TypeInfo(TSampleRec))); ShowMessage(GetTypeData(TypeInfo(TSampleRec)).elSize.ToString); ShowMessage(GetTypeData(TypeInfo(TSampleRec)).RecSize.ToString); ShowMessage(GetTypeData(TypeInfo(TSampleRec)).ManagedFldCount.ToString); var info: PRttiInfo := TypeInfo(TSampleRec); var recSize: Integer; for var recField: TRttiRecordAllField in info.RecordAllFields(recSize) do begin ShowMessage(Format('Offset: %d, FieldName: %s, FieldType: %s, FieldSize: %d', [ recField.Offset, recField.Name^, recField.TypeInfo.RawName, recField.TypeInfo.RttiSize])); end; ShowMessage(recSize.ToString); Thomas |
Alle Zeitangaben in WEZ +1. Es ist jetzt 10:53 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz