首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >重构TClientdataset

重构TClientdataset
EN

Stack Overflow用户
提问于 2009-01-18 20:15:54
回答 2查看 574关注 0票数 3

是否可以在不丢失数据的情况下重构TClientDataSet XML文件?有没有演示应用程序或源代码来展示如何进行这样的重构?

EN

回答 2

Stack Overflow用户

发布于 2009-01-18 21:47:24

是也不是,xml文档是使用XLST进行转换的,因此它需要符合该模板才能被TClientDataSet读取。

然而,这也意味着您也可以将文档转换为您自己喜欢的任何格式到单独的文档中,您只是不能将转换后的文档直接加载到TClientDataSet中。

编辑:哦,忘了贴一个例子了。

代码中心上的This project显示了从客户端数据集到ADO记录集的转换。

票数 1
EN

Stack Overflow用户

发布于 2017-04-05 21:59:45

为了更改磁盘上的CDS结构,我使用了下面列出的一个子类。我们以二进制格式将数据写入流(在压缩/加密之前),但对于XML格式,它的工作方式应该大致相同。

如果需要在已保存的数据集中添加/删除任何字段或更改字段定义,则只需增加数据集表版本即可。每次打开数据集时,它都会将保存的版本号与当前版本号进行比较。如果保存的表是旧的,它将被复制到新结构中,所以如果您需要进行更改,您将在第一次重新加载该表时受到性能影响,但之后应该像往常一样从磁盘加载。

因此,如果您在执行合并之后将CDS保存回磁盘,那么您的XML结构将以CDS友好的格式更新。

代码语言:javascript
复制
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; 
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/455815

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档