将数据集字段值分配给由以下方法执行的属性:
var
lvRuntimeContext: TRttiContext;
lvRuntimeType: TRttiType;
lvProp: TRttiProperty;
lvAttr: TCustomAttribute;
lvCol: EntityColumnAttrib;
begin
if DataAccess.DataSet.Active then
begin
lvRuntimeContext := TRttiContext.Create;
try
lvRuntimeType := lvRuntimeContext.GetType(EntityColumnClassType);
for lvProp in lvRuntimeType.GetProperties do
for lvAttr in lvProp.GetAttributes do
if lvAttr is EntityColumnAttrib then
begin
lvCol := (lvAttr as EntityColumnAttrib);
if lvCol.InCurrentTable then
case lvCol.FieldType of
ftBytes: begin
end;
ftDateTime: lvProp.SetValue(ASystemColumns, TValue.From<TDateTime>(DataAccess.DataSet.FieldByName(lvCol.FieldName).AsDateTime));
else
lvProp.SetValue(ASystemColumns, TValue.From<Variant>(DataAccess.DataSet.FieldByName(lvCol.FieldName).AsVariant));
end;
end;
finally
lvRuntimeContext.Free;
end;
end;
在我的一个类中有一个类型为 TMemoryStream 的属性,我想从DataSet字段(SQL Server:二进制类型)赋值给它,怎么能我用这种方法做到了吗?
答案 0 :(得分:3)
您可以使用DataSet的CreateBlobStream()
方法获取所需TStream
的只读TField
,随身携带所需内容,然后在完成后将其释放。
如果可能,您应该将您的媒体资源更改为接受任何常规TStream
,而不仅仅是TMemoryStream
。这样,您可以通过RTTI直接将blob TStream
分配给您的属性(TValue
可以从任何TObject
指针隐式创建):
var
lvRuntimeContext: TRttiContext;
lvRuntimeType: TRttiType;
lvProp: TRttiProperty;
lvAttr: TCustomAttribute;
lvCol: EntityColumnAttrib;
lStrm: TStream;
begin
if DataAccess.DataSet.Active then
begin
lvRuntimeContext := TRttiContext.Create;
try
lvRuntimeType := lvRuntimeContext.GetType(EntityColumnClassType);
for lvProp in lvRuntimeType.GetProperties do
begin
for lvAttr in lvProp.GetAttributes do
begin
if lvAttr is EntityColumnAttrib then
begin
lvCol := (lvAttr as EntityColumnAttrib);
if lvCol.InCurrentTable then
begin
case lvCol.FieldType of
ftBytes: begin
lStrm := DataAccess.DataSet.CreateBlobStream(DataAccess.DataSet.FieldByName(lvCol.FieldName), bmRead);
try
lvProp.SetValue(ASystemColumns, lStrm);
finally
lStrm.Free;
end;
end;
ftDateTime: begin
lvProp.SetValue(ASystemColumns, TValue.From<TDateTime>(DataAccess.DataSet.FieldByName(lvCol.FieldName).AsDateTime));
end;
else
lvProp.SetValue(ASystemColumns, TValue.From<Variant>(DataAccess.DataSet.FieldByName(lvCol.FieldName).AsVariant));
end;
end;
end;
end;
end;
finally
lvRuntimeContext.Free;
end;
end;
end;
如果属性必须仅继续使用TMemoryStream
,则必须创建临时TMemoryStream
对象,将blob数据复制到其中(可以使用TStream.CopyFrom()
),然后将其分配给属性:
var
lvRuntimeContext: TRttiContext;
lvRuntimeType: TRttiType;
lvProp: TRttiProperty;
lvAttr: TCustomAttribute;
lvCol: EntityColumnAttrib;
lBlobStrm: TStream;
lMemStrm: TMemoryStream;
begin
if DataAccess.DataSet.Active then
begin
lvRuntimeContext := TRttiContext.Create;
try
lvRuntimeType := lvRuntimeContext.GetType(EntityColumnClassType);
for lvProp in lvRuntimeType.GetProperties do
begin
for lvAttr in lvProp.GetAttributes do
begin
if lvAttr is EntityColumnAttrib then
begin
lvCol := (lvAttr as EntityColumnAttrib);
if lvCol.InCurrentTable then
begin
case lvCol.FieldType of
ftBytes: begin
lMemStrm := TMemoryStream.Create;
try
lBlobStrm := DataAccess.DataSet.CreateBlobStream(DataAccess.DataSet.FieldByName(lvCol.FieldName), bmRead);
try
lMemStrm.CopyFrom(lBlobStrm, 0);
finally
lBlobStrm.Free;
end;
lMemStrm.Position := 0;
lvProp.SetValue(ASystemColumns, lMemStrm);
finally
lMemStrm.Free;
end;
end;
ftDateTime: begin
lvProp.SetValue(ASystemColumns, TValue.From<TDateTime>(DataAccess.DataSet.FieldByName(lvCol.FieldName).AsDateTime));
end;
else
lvProp.SetValue(ASystemColumns, TValue.From<Variant>(DataAccess.DataSet.FieldByName(lvCol.FieldName).AsVariant));
end;
end;
end;
end;
end;
finally
lvRuntimeContext.Free;
end;
end;
end;