想学 TClientDataSet 是在 2009 年 5 月, 但当时学不动; 现在好了, 有源码了(DBClient.pas).

希望这次学习能对其内存协调方式有所了解, 顺便学点数据库的知识.

TClientDataSet 是一个内存数据集(说"数据表"对不住它), 其内存数据可存取到本地(*.cds 或 *.xml 格式).

用 TDBGrid 可方便查看其内存数据, 但需要用数据源组件(如: TDataSource)桥接一下:
TDBGrid.DataSource ← TDataSource.DataSet ← TClientDataSet

Program Files\Common Files\CodeGear Shared\Data 下有官方提供的测试数据, 下面程序可浏览这些数据:



//假定已在设计时挂接好: ClientDataSet1、DataSource1、DBGrid1, 并添加一个 ListBox1

uses IOUtils, Types;

var DataPath: string;

procedure TForm1.FormCreate(Sender: TObject);
var
  sArr: TStringDynArray;
  s: string;
begin
  { 获取测试数据所在的路径 }
  DataPath := GetEnvironmentVariable('COMMONPROGRAMFILES') + '\CodeGear Shared\Data\';
  { 获取路径下所有 cds 文件 }
  sArr := TDirectory.GetFiles(DataPath, '*.cds');
  { 添加到列表 }
  for s in sArr do ListBox1.Items.Add(ExtractRelativePath(DataPath, s));
end;

procedure TForm1.ListBox1Click(Sender: TObject);
begin
  ClientDataSet1.LoadFromFile(DataPath + ListBox1.Items[ListBox1.ItemIndex]);
end;


其中的:
procedure TForm1.ListBox1Click(Sender: TObject);
begin
  ClientDataSet1.LoadFromFile(DataPath + ListBox1.Items[ListBox1.ItemIndex]);
end;

//可换成:
procedure TForm1.ListBox1Click(Sender: TObject);
begin
  ClientDataSet1.Active := False;
  ClientDataSet1.FileName := DataPath + ListBox1.Items[ListBox1.ItemIndex];
  ClientDataSet1.Active := True;
end;

//或换成:
procedure TForm1.ListBox1Click(Sender: TObject);
begin
  ClientDataSet1.Close;
  ClientDataSet1.FileName := DataPath + ListBox1.Items[ListBox1.ItemIndex];
  ClientDataSet1.Open;
end;


从源码中看 Open/Close 方法和 Active 属性的关系:
{ TClientDataSet 的继承关系: TDataSet - TCustomClientDataSet - TClientDataSet }
procedure TDataSet.Open;
begin
  Active := True;
end;

procedure TDataSet.Close;
begin
  Active := False;
end;


从源码中查看 LoadFromFile 对 Open/Close 方法的调用:
procedure TCustomClientDataSet.LoadFromFile(const FileName: string = '');
var
  Stream: TStream;
begin
  Close;
...
  LoadFromStream(Stream); { LoadFromFile 调用了 LoadFromStream}
...
end;

procedure TCustomClientDataSet.LoadFromStream(Stream: TStream);
begin
  Close;
  ReadDataPacket(Stream, False);
  Open;
end;

posted on 2010-01-20 10:06  万一  阅读(7405)  评论(2编辑  收藏  举报