I’m curious to know if there are simple ways of handling the issue of child records that get orphaned when the user bails on the parent record. I’ve been handling this by hiding the child Browse on the form until the parent record is saved. Self.Request=InsertRecord then gets changed to Self.Request =ChangeRecord. That works – unless, the GUID field in the parent suddenly gets cleared. I spent a good bit of time trying to track down why my GUID field was getting blanked when adding a child record (after the parent was already saved). So, I’m thinking there’s a better way.
I have Super Invoice, but I prefer not to use Edit in Place in this instance.
There’s obviously something that I’m not grasping. I’m curious to see if there’s a better way.
The “simple” way is to set up your dictionary so that the Parent-Child relationship uses AutoInc on the parent Primary Key field and Cascade on delete in the relationship specification. In that way your parent record gets saved when you create the record and your children get deleted if you cancel the insert.
You can also specify Restrict on Delete which will force your user to delete the child records if they cancel the insert of the parent.
Then the templates will handle it all for you.
Since you are using Super Invoice you should probably ask the supplier (Mike ?) how it is handled by that template?
There is a technique using edit tables you can use that gets around all this nicely. It is a bit more effort though.
Basically you have 2 sets of tables, the real tables and an identical set of edit tables.
When you create a new thing you do in the edit tables and at the end if they press ok, you copy everything to the real tables. For changes you copy from the real tables to the edit tables make changes and copy back.
Advantage of this is you get locking of the thing, because you won’t allow the same thing twice in the edit tables. You get an all or nothing approach to making changes, and anything in the edit tables can be deleted.
Another way, depending on the capabilities of your database is (i.e. you need a SQL database that handles deferred constraints), is:
Set up the child table’s foreign key constraint back to parent as Deferred.
Do not save the parent before you start entering children
But you do need to get the parent ID, whether that is a GUID or something else.
Turn off UseLogoutOnInsert on the child and the parent.
Explicitly start a logout before you start entering any children, and set UseLogout on the parent
As you enter the children they will be added to the database, but the database will not check (until the commit) that the foreign constraint is met (i.e. that the parent exists, because at this point it doesn’t. Turning off UseLogoutOnInsert will stop the child insertion trying toe start its own logout.
When you get to the end of the form, you either commit, which will commit both the parent and the children, or you cancel, and the database will abandon all the uncommitted rows in the transaction, both the parent and the children.
I know this flies in the face of some people’s belief that logouts should be kept really short, but in a “proper” database, the only rows involved are the not-yet added single parent and its children, which should cause no trouble.
PurpleEdge’s method should work too. The CancelAutoInc method calls the RelationManager.Delete, so that will get rid of the children even if the parent was never really added.