delphi 如何在释放查询后继续在TDBGrid中显示数据?

1u4esq0p  于 2023-06-05  发布在  其他
关注(0)|答案(1)|浏览(193)

我试图从数据库中获取数据并填充TDBGrid。当使用try/finally块时,DataSource中的所有记录都被清除,因为我在finally中执行Free
我看过Google,所有示例都在finally块中使用q.Free

procedure TSubjektiForm.FormActivate(Sender: TObject);
var
  q : TZQuery;
  ds : TDataSource;
begin
  q := TZQuery.Create(nil);
  ds := TDataSource.Create(nil);

  try
    DBGrid1.DataSource := ds;
    ds.DataSet := q;

    q.Active := False;
    q.SQL.Clear;
    q.Connection := DataModule1.ZConnection1;
    q.SQL.Text := 'SELECT id, naziv, telefon FROM subjekti';
    q.Open;
  finally
    q.Free;
  end;
end;

如果删除q.Free,则数据显示在TDBGrid中。
我读到:
Finally关键字用于标记Try语句中最后一个语句块的开始。不管Try语句中发生了什么,它们都会被执行。
但我的问题是,我如何才能释放这个查询?还有别的办法吗?

  • 对不起,愚蠢的问题,我是新的 Delphi ,我来自C#,这是真的不同!*
o75abkj4

o75abkj41#

与C#不同, Delphi 中的对象不进行引用计数或垃圾收集。当你在 Delphi 中Free()一个对象时,它会立即消失。在C#中,等价的是在实现IDisposable的对象上调用Dispose()
TDBGrid仅显示可通过指定的TDataSource访问的数据。您的TDataSource只是将数据连接到网格的中介。不复制数据。TZQuery保存了实际的数据,所以当你释放这个对象时,它和它的数据就消失了。这就是为什么在运行finally后,网格不会显示任何内容。
因此,您需要确保正在创建的TZQueryTDataSource对象的寿命比检索数据的过程长。
如果您不打算在设计时将组件放到Form/DataModule上(您应该这样做),那么至少在Form/DataModule的构造函数或OnCreate事件中创建它们。您可以将您的Form/DataModule指定为它们的Owner,以便在释放Form/DataModule时释放它们。
例如:

type
  TSubjektiForm = class(TForm) // or your DataModule
    procedure FormCreate(Sender: TObject);
    procedure FormActivate(Sender: TObject);
    ...
  private
    Query : TZQuery;
    ...
  end;

...

procedure TSubjektiForm.FormCreate(Sender: TObject);
var
  ds : TDataSource;
begin
  Query := TZQuery.Create(Self);
  Query.Connection := DataModule1.ZConnection1;

  ds := TDataSource.Create(Self);
  ds.DataSet := Query;

  DBGrid1.DataSource := ds;
end;

procedure TSubjektiForm.FormActivate(Sender: TObject);
begin
  Query.Close;
  Query.SQL.Text := 'SELECT id, naziv, telefon FROM subjekti';
  Query.Open;
end;

相关问题