我正在使用Delphi6
并有一个数据模块,ADO
DataSet
它由两种形式使用,formA 和 FormB。每个表格都有一个Dataset.Open()
inOnCreate
和Dataset.Close()
in OnClose
。如果两个表单同时打开并且 formB 关闭,则数据集在 formA 中关闭。我该如何防止这种情况,基本上我需要为每个表单提供单独的数据集实例,但同时使用数据模块。
4 回答
对于每个表单,您可能需要一个来自数据模块的单独实例。
如果您真的想在两种表单中使用相同的数据模块实例,那么您必须从数据模块打开和关闭数据集,添加一些引用计数机制。
通常,您可以通过在数据模块中打开数据集和关闭数据集的过程以及用于计算打开和关闭调用的整数来做到这一点。打开数据集的过程实际上只在第一次调用时打开它,在任何后续调用中只会增加计数器。close 过程在每次调用时递减计数器,并在计数器值回落到 0 时关闭数据库。
实现您想要的最简单的方法是为每个表单创建一个数据模块的实例,并将其传递给表单,以便在表单关闭时可以释放它:
var
Data: TDataModule;
begin
Data := T<YourDataModule>.Create(Self);
try
Form := T<YourForm>.Create(Self);
Form.DataModule := Data;
Data.Name := '';
except
Data.Free;
raise;
end;
Form.Show;
end;
将 DataModule 的名称设置为空字符串是为了确保 VCL 用于将数据感知控件连接到其数据源/数据集的逻辑是使用新创建的实例而不是第一个实例完成的。
在表单的 OnClose 处理程序(或其析构函数)中,确保释放数据模块。
您是否尝试同时从 FormA 和 FormB 访问相同的数据集,同时显示不同的数据,如果是这样:
使用 TClientDataSet 和 TDataSetProvider 从您的 ADO 数据集中加载数据。然后使用 ClientDataSet.CloneCursor 克隆游标,您将获得一个指向相同数据的单独游标。然后将它们传递给表单或将 FormA 的控件分配给 ClientDataSetA,将 FormB 的控件分配给克隆 ClientDataSetB。两种形式的读取、写入和更新都会更改基础数据集,然后可以通过 ADO 数据集通过 DataSetProviders ApplyUpdates 将更新应用到数据库。
在这里寻求帮助:http ://www.podgoretsky.com/ftp/docs/Delphi/D5/dg/5_ds3.html 或者有一本 Cary Jenson 写的非常好的书:http: //www.jensendatasystems.com/ cdsbook/ (免费插件,但它是一个很好的阅读)
正如您所说,您需要单独的实例,那么我的解决方案是在每个表单声明中都有一个 Datamodule 变量:
TForm1 = class(TForm)
...
private
fDatamodule : TDatamodule1;
...
end;
procedure TForm1.FormCreate(Sender : TObject)
begin
fDatamodule := TDatamodule1.Create(self);
MyDatasource.Dataset := fDatamodule.MyDataset;
end;
(对 Form2 等重复)
您有相同的数据模块,实例化了两次,因此彼此完全分离,但在每个表单中使用相同的业务逻辑。
在讨论主题时,请确保您的数据模块代码不引用任何一种形式。这是不好的做法。