Отдельные экземпляры набора данных с использованием модулей данных в Delphi

Я использую Delphi6 и иметь модуль данных с ADODataSet который используется двумя формами, formA и FormB. Каждая форма имеет Dataset.Open() в OnCreate а также Dataset.Close() в OnClose, Если обе формы открыты одновременно, а formB закрыта, набор данных закрывается в formA. Как я могу предотвратить это, по сути, мне нужны отдельные экземпляры набора данных для каждой формы, но в то же время использовать модуль данных.

4 ответа

Решение

Самый простой способ добиться того, чего вы хотите - это создать экземпляр модуля данных для каждой формы и передать его в форму, чтобы его можно было освободить при закрытии формы:

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 (или его деструкторе) обязательно освободите модуль данных.

Вероятно, вам нужен отдельный экземпляр от модуля данных для каждой формы.

Если вы действительно хотите использовать один и тот же экземпляр модуля данных в обеих формах, вам нужно открыть и закрыть набор данных из модуля данных, добавив механизм подсчета ссылок.

Как правило, вы делаете это, имея процедуру для открытия набора данных и одну для его закрытия в модуле данных и целое число для подсчета вызовов открытия и закрытия. Процедура, которая открывает набор данных, фактически открывает его только при первом вызове, при любом последующем вызове просто увеличивает счетчик. Процедура сближения уменьшает счетчик при каждом вызове и закрывает базу данных, когда значение счетчика возвращается к 0.

Поскольку вы сказали, что вам нужны отдельные экземпляры, тогда мое решение будет иметь переменную Datamodule в каждом объявлении формы:

TForm1 = class(TForm)
...
private
  fDatamodule : TDatamodule1;
...
end;

procedure TForm1.FormCreate(Sender : TObject)
begin
  fDatamodule := TDatamodule1.Create(self);
  MyDatasource.Dataset := fDatamodule.MyDataset;
end;

(повторите для Form2 и т. д.)

У вас один и тот же модуль данных, он создается дважды и, таким образом, полностью отделен друг от друга, но использует одну и ту же бизнес-логику в каждой форме.

Хотя по теме, убедитесь, что ваш код модуля данных не содержит ссылки ни на одну из форм. Это плохая практика.

Вы пытаетесь получить доступ к одному и тому же набору данных из 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 Или есть действительно хорошая книга Кэри Дженсон: http://www.jensendatasystems.com/cdsbook/(бесплатный плагин, но он хорошо читается)

Другие вопросы по тегам