separate dataset instances using datamodules in delphi

杀马特。学长 韩版系。学妹 提交于 2019-12-19 10:05:36

问题


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 in 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.


回答1:


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.




回答2:


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.




回答3:


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)




回答4:


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.



来源:https://stackoverflow.com/questions/6760750/separate-dataset-instances-using-datamodules-in-delphi

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!