一个TClientDataSet的XML文件能否在不丢失数据的情况下进行重构?是否有演示应用程序或源代码展示如何进行这样的重构?
一个TClientDataSet的XML文件能否在不丢失数据的情况下进行重构?是否有演示应用程序或源代码展示如何进行这样的重构?
是和不是,XML文档使用XLST进行转换,因此需要符合该模板才能被TClientDataSet读取。
但这也意味着您可以将文档转换为任何您喜欢的格式,并将其转换为单独的文档,只是不能直接将转换后的文档加载到TClientDataSet中。
编辑: 哎呀,忘记发布一个例子了。
此项目在代码中心显示了从客户端数据集到ADO记录集的转换。
TCDS = class(TCustomClientDataset)
private
fTableVersion: integer;
/// <summary> Copies records from source with potentially different table
/// structure/field defs from self, providing defaults for missing fields</summary>
procedure CopyFromDataset(const ASource: TCustomClientDataset);
/// <summary>Provide a default value, if necessary, for any new fields</summary>
function GetDefaultValue(const AFieldName: string): variant;
public
procedure LoadFromStream(AStream: TStream);
procedure SaveToStream(AStream: TStream);
end;
procedure TCDS.LoadFromStream(AStream: TStream);
var
ATemp: TCDS;
APersistedVersion: integer;
begin
AStream.ReadData(APersistedVersion);
if APersistedVersion = fTableVersion then
begin
Close;
ReadDataPacket(AStream, True);
Open;
end
else if APersistedVersion < fTableVersion then
begin
// It's an old table structure:
// - Load old structure into temp CDS
// - Merge temp CDS records into new structure
ATemp := TCDS.Create;
try
ATemp.Close;
ATemp.ReadDataPacket(AStream, True);
ATemp.Open;
CopyFromDataset(ATemp);
finally
FreeAndNil(ATemp);
end;
end;
end;
procedure TCDS.SaveToStream(AStream: TStream);
begin
AStream.WriteData(fVersionNumber);
WriteDataPacket(AStream, True);
end;
procedure TCDS.CopyFromDataset(const ASource: TCustomClientDataset);
var
ACurrentFieldNames: TStrings;
i: integer;
begin
// Assuming we don't want to keep any records already in dataset
EmptyDataSet;
ACurrentFieldNames := TStringList.Create;
try
Fields.GetFieldNames(ACurrentFieldNames);
for i := 0 to ACurrentFieldNames.Count-1 do
ACurrentFieldNames.Objects[i] := ASource.Fields.FindField(ACurrentFieldNames[i]);
ASource.First;
while not ASource.Eof do
begin
Append;
for i := 0 to Fields.Count-1 do
begin
if Assigned(ACurrentFieldNames.Objects[i]) then
Fields[i].Value := TField(ACurrentFieldNames.Objects[i]).Value
else if Fields[i].Required then
Fields[i].Value := GetDefaultValue(ACurrentFieldNames[i]);
end;
Post;
ASource.Next;
end;
finally
FreeAndNil(ACurrentFieldNames);
end;
end;