Edit DataSet Entity in dialog

Hi,

I have a TAureliusDataSet setup (together with connection and manager) set up in my main form.  The DataSet's objects are displayed in a (DevExpress) grid and displays only a few of the available fields.

I am now trying to edit the currently selected object (entity) by using the following code assigned to a button:

procedure TfrmMain.btnEditClick(Sender: TObject);
var
  dlgData: TdlgData;
begin
  dlgData := TdlgData.Create(nil);
  try
    dlgData.DialogDataSet.Manager := amTest.ObjManager;   // amTest is a TAureliusManager
    dlgData.DialogDataSet.SetSourceObject(MainDataSet.Current<TMyEntity>);
    dlgData.DialogDataSet.Open;
    if dlgData.ShowModal = mrOK then
    begin
      amTest.ObjManager.Flush;
    end;
  finally
    // dlgData.DialogDataSet closed in onDestroy...
    dlgData.Free;
  end;
end;

The strange things is that there are no exceptions or warnings, but all edits are lost when I click OK (ShowModal = mrOK).  Nothing is changed in the grid (even after MainDataSet.Refresh) and neither is anything updated in the database.  Can you see anything wrong with this code? Am I missing something?  I can confirm the call to Flush is executed (breakpoint).

Regards,
Mark

Never mind, I did miss something (the obvious).  

I forgot the call to dlgData.DialogDataSet.Post.  After that call frmMain.MainDataSet.Refresh and all works OK and as expected/desired.

Thanks, Mark




Further to the above, I am also trying to create a new object (TMyEntity), edit it in a dialog and then depending on whether OK or Cancel is clicked, Post or Cancel the dataset on the dialog. I currently have the following code:

FMyEntityList: TList<TMyEntity>;  // Global for TfrmMain

procedure TfrmMain.btnNewClick(Sender: TObject);
var
  dlgData: TdlgData;
  objNew: TMyEntity;
begin
  dlgData := TdlgData.Create(nil);
  objNew := TMyEntity.Create;
  try
    dlgData.SetDataObject(amTest.ObjManager, objNew); // Sets Manager and SourceObject of dlgData.DialogDataSet
    if dlgData.ShowModal = mrOK then
    begin
      FMyEntityList.Add(objWell);
      MainDataSet.Refresh;
    end;
  finally
    dlgData.Free;
  end;
end;

For good order, both DataSets (Main Form and Dialog) share the same ObjectManager (amTest.ObjManager) and FMyEntityList is the source list for the DataSet on the main form, which is displayed in a grid.

Unlike when editing, I couldn't get the grid in the Main Form to display the new record/entity until I added a reference to it in FMyEntityList (which makes sense, it just took me some time to realize this). 

As I am still somewhat struggling with understanding of ownership and memory management, I have the following questions (merely looking for confirmation):

  1. I am presuming that when posting the (new) entity object (with the dataset's Manager property set to the shared manager, destruction of the entity objects is handled by the Manager.  As such, the TList can be considered a list of pointers (to the objects) and only needs to be destroyed (Free).  The entity objects are destroyed when the Manager is destroyed.  Correct? If so, then there's no problem adding the entity (or rather the pointer to it) to the TList and the local variable just going out of scope (i.e. not freed).
  2. If the above is correct, FEntityList should NOT be declared as a TObjectList<T> with OwnsObjects = true to prevent destroying the entity objects with the list, possibly causing trouble when destroying the Manager (access violation). Correct?
  3. In general (rule of thumb); declare a TObjectList<T> for collections when not using a Manager and declare a TList<T> when entity objects are managed by a Manager. Does that make sense?
  4. When a "data action" (Save, Update, etc) is executed for an Entity (e.g. Manager.Save(MyEntity)), the Entity is from then on attached to (and managed by) the Manager (i.e. destruction is handled by the Manager). This automatically happens when Posting entities through a DataSet with the Manager property set? Is my understanding correct?
Looking forward to your replies.  Thanks in advance for your time and consideration!
Regards, Mark
Correction: FMyEntityList.Add(objWell) should read FMyEntityList.Add(objNew)

Hello Mark,


1. Correct.

2. Correct.

3. Yes. But you can also manually check for objects to be destroyed. using Manager.IsAttached(Obj) to see if the object is managed or not, and thus is going to be destroyed by the manager.

4. Yes, correct.

So you are having a good understanding of things! :-)
But one note: if you are dealing with the dataset, I personally think it's better to perform a Dataset.Insert (or Append) instead of using TMyEntity.Create.
When you call Insert or Append, AureliusDataset already creates a new instance of the entity for you, which you can access using the Current property. And it takes care of destroying it or not, depending if you for example do a Post or Cancel. And, also, it also adds the new posted object to the list, so most of that mechanism is done automatically by the dataset.