Вы можете проявить творческий подход, используя подход типа addref / release. Просто создайте несколько функций и целочисленную переменную в вашем общем модуле данных, чтобы творить чудеса, и обязательно вызывайте их. Ниже приведен частичный код:
TDMShared = class(tDataModule)
private
fQueryCount : integer; // set to 0 in constructor
public
function GetQuery : tDataset;
procedure CloseQuery;
end;
function TDMShared.GetQuery : tDataset;
begin
inc(fQueryCount);
if fQueryCount = 1 then
SharedDatsetQry.open;
Result := shareddatasetqry; // your shared dataset here
end;
procedure TDMShared.CloseQuery;
begin
dec(fQueryCount);
if fQueryCount <= 0 then
shareddatasetqry.close; // close only when no refs left.
end;
РЕДАКТИРОВАТЬ: Чтобы сделать это с несколькими запросами, вам нужен контейнер для хранения ссылок на запросы и способ манипулировать ими. Для этого хорошо работает tList. Вам нужно будет внести соответствующие изменения для вашего потомка TDataset, а также создать функцию FreeAndNil, если вы используете более старую версию Delphi. Концепция, которую я использовал для этого, состояла в том, чтобы поддерживать список всех запрашиваемых вами запросов и манипулировать ими с помощью дескриптора, который фактически является индексом запроса в списке. Метод FreeUnusedQueries предназначен для освобождения любых объектов, у которых больше нет ссылки ... это также можно сделать как часть метода запроса close, но я разделил его для обработки случаев, когда конкретный запрос должен был быть повторно открыт другим модуль.
Procedure TDMShared.DataModuleCreate(Sender:tObject);
begin
dsList := tList.create;
end;
Function TDMShared.CreateQuery(aSql:String):integer;
var
ds : tAdoDataset;
begin
// create your dataset here, for this example using TADODataset
ds := tAdoDataset.create(nil); // self managed
ds.connection := database;
ds.commandtext := aSql;
ds.tag := 0;
Result := dsList.add(ds);
end;
function TDMShared.GetQuery( handle : integer ) : tDataset;
begin
result := nil;
if handle > dsList.count-1 then exit;
if dsList.Items[ handle ] = nil then exit; // handle already closed
result := tAdoDataset( dsList.items[ handle ]);
Inc(Result.tag);
if Result.Tag = 1 then
Result.Open;
end;
procedure TDMShared.CloseQuery( handle : integer );
var
ds : tAdoDataset;
begin
if handle > dsLIst.count-1 then exit;
ds := tAdoDataset( dsList.items[ handle ]);
dec(ds.Tag);
if ds.Tag <= 0 then
ds.close;
end;
procedure TDMShared.FreeUnusedQueries;
var
ds : tAdoDataset;
ix : integer;
begin
for ix := 0 to dsList.Count - 1 do
begin
ds := tAdoDataset(dsLIst.Items[ ix ]);
if ds.tag <= 0 then
FreeAndNil(dsList.Items[ix]);
end;
end;
procedure TDMShared.DataModuleDestroy(Sender: TObject);
var
ix : integer;
begin
for ix := 0 to dsList.count-1 do
begin
if dsLIst.Items[ix] <> nil then
FreeAndNil(dsLIst.Items[ix]);
end;
dsList.free;
end;