就我而言,我只想序列化 _recordsets 所以我的解决方案是:
1)获取所有_Recordset类型字段:
function Test.GetRecordsetFieldsFromObject(
AObject: TObject): TStringList;
var
Obj: TRttiType;
Rtti: TRTTIContext;
ObjField: TRttiField;
IntfObj: IInterface;
rsOut: _recordset;
begin
Result := TStringList.Create;
Obj := Rtti.GetType(AObject.ClassType);
for ObjField in Obj.GetFields do
if ObjField.FieldType.TypeKind = tkInterface then
begin
IntfObj := ObjField.GetValue(AObject).AsInterface;
if IntfObj.QueryInterface(_Recordset, rsOut) = 0 then
begin
Result.Add(ObjField.Name);
rsOut := nil;
end;
end;
end;
2) 为创建的每个字段注册转换器和还原器
for FieldName in FieldNameList do
begin
JsonMarshal.RegisterConverter(TFoo, FieldName, function(Data: TObject; Field: String): TListOfStrings
var
Obj: TRttiType;
ObjField: TRttiField;
rsProp: _Recordset;
strStream: TStringStream;
begin
SetLength(Result, 1);
strStream := TStringStream.Create;
try
Obj := Rtti.GetType(data.ClassType);
ObjField := Obj.GetField(Field);
rsProp := ObjField.GetValue(Data).AsInterface as _Recordset;
rsProp.Save(TStreamAdapter.Create(strStream) as IUnknown, adPersistXML);
Result[0] := strStream.DataString;
finally
rsProp := nil;
strStream.Free;
end;
end);
JsonUnMarshal.RegisterReverter(TFoo, FieldName, procedure(Data: TObject; Field: String; Args: TListOfStrings)
var
Obj: TRttiType;
ObjField: TRttiField;
rsProp: _Recordset;
strStream: TStringStream;
begin
rsProp := coRecordset.Create;
strStream := TStringStream.Create(Args[0]);
try
Obj := Rtti.GetType(data.ClassType);
ObjField := Obj.GetField(Field);
strStream.Position := 0;
rsProp.Open(TStreamAdapter.Create(strStream) as IUnknown, EmptyParam, adOpenUnspecified, adLockUnspecified, 0);
ObjField.SetValue(Data, TValue.From<_Recordset>(rsProp));
finally
rsProp := nil;
strStream.Free;
end;
end);
end;