I want to post in memory some child rows, and then conditionally post them, or don't post them to an underlying SQL database, depending on whether or not a parent row is posted, or not posted. I don't need a full ORM, but maybe just this:
- User clicks Add doctor. Add doctor dialog box opens.
- Before clicking Ok on Add doctor, within the Add doctor dialog, the user adds one or more patients which persist in memory only.
- User clicks Ok in Add doctor window. Now all the patients are stored, plus the new doctor.
- If user clicked Cancel on the doctor window, all the doctor and patient info is discarded.
Try if you like, mentally, to imagine how you might do the above using delphi data aware controls, and TADOQuery or other ADO objects. If there is a non-ADO-specific way to do this, I'm interested in that too, I'm just throwing ADO out there because I happen to be using MS-SQL Server and ADO in my current applications.
So at a previous employers where I worked for a short time, they had a class called TMasterDetail
that was specifically written to add the above to ADO recordsets. It worked sometimes, and other times it failed in some really interesting and difficult to fix ways.
Is there anything built into the VCL, or any third party component that has a robust way of doing this technique? If not, is what I'm talking about above requiring an ORM? I thought ORMs were considered "bad" by lots of people, but the above is a pretty natural UI pattern that might occur in a million applications. If I was using a non-ADO non-Delphi-db-dataset style of working, the above wouldn't be a problem in almost any persistence layer I might write, and yet when databases with primary keys that use identity values to link the master and detail rows get into the picture, things get complicated.
Update: Transactions are hardly ideal in this case. (Commit/Rollback is too coarse a mechanism for my purposes.)
OnInsert
of the MD CDS, I create an empty row in the Hosp CDS as well (they're required to be on-staff at one). The dialog allows adding multiple hosp. rows, but doesn't populate any of the MD IDs. In theOnPost
event, I do the update of the underlying MD table (fetching the new ID), update the rows in the hosp CDS, and insert those as well. In the dialog, theCancel
button simply discards the rows in both the MD and hosp. CDS. It's not quite auto-master-child, but it works, and it's all in a datamodule. :-) – Levo