想學 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;