开发者

separate dataset instances using datamodules in delphi

开发者 https://www.devze.com 2023-03-21 21:40 出处:网络
I am using Delphi6 and have a data module with an ADO DataSet which is used by two forms, formA and FormB. Each form has a Dataset.Open() in OnCreate and Dataset.Close() in OnClose. If both forms are

I am using Delphi6 and have a data module with an ADO DataSet which is used by two forms, formA and FormB. Each form has a Dataset.Open() in OnCreate and Dataset.Close() in OnClose. If both forms are open simultaneously and formB is closed the dataset is closed i开发者_运维百科n formA. How can I prevent this, essentially I need separate instances of the dataset for each form but at the same time use the datamodule.


The simplest way to achieve what you want is to create an instance of the data module for each form, and pass it to the form so it can be freed when the form is closed:

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;

Setting the DataModule's Name to an empty string is done to ensure that the VCL's logic for hooking up data aware controls to their datasource/dataset is done using the newly created instance, instead of the first ever instance.

In the Form's OnClose handler (or its destructor) make sure to free the data module.


Probably you need a separate instance from the datamodule for each form.

If you really want to use the same datamodule instance form both forms, then you have to open and close the dataset from the datamodule, adding some reference counting mechanism.

Tipically you do that by having a procedure for opening the dataset and one for closing it in the datamodule and an integer to count the open and close calls. The procedure which opens the dataset actually opens it only at the first call, at any subsequent call just incremets the counter. The closer procedure decrements the counter at each call, and closes the database when the counter value drops back to 0.


Are you trying to access the same dataset from FormA and FormB at the same time while displaying different data, if so:

Use a TClientDataSet and a TDataSetProvider to load the data from you ADO dataset. Then clone the cursor using ClientDataSet.CloneCursor, you get a seperate cursor to the same data. Then pass them to the forms or assign the controls of FormA to ClientDataSetA and FormB to the clone ClientDataSetB. Reads, writes and updates from both forms change the underlying dataset which can then apply the updates to the database through the ADO dataset later via the DataSetProviders ApplyUpdates.

Look here for some help: http://www.podgoretsky.com/ftp/docs/Delphi/D5/dg/5_ds3.html Or there is a really good book by Cary Jenson: http://www.jensendatasystems.com/cdsbook/ (free plug, but it is a good read)


As you said you need seperate instances, then my solution would be to have a Datamodule variable in each form declaration:

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

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

(repeat for Form2 etc)

You have the same datamodule, instanciated twice and thus completely seperate from each other, but utilising the same business logic in each form.

Whilst on the subject, ensure your datamodule code does not make reference to either form. This is bad practice.

0

精彩评论

暂无评论...
验证码 换一张
取 消