General database & bound/unbound controls question
Posted: Tue 23 Mar 2010 05:47
This post is going to be quite long and I apologize for the long read, but I have some issues that I have some questions on and would like to get some input from other users. This is not so much technical coding questions, so much as it is general end user usabilty and flow.
The main point of my post is...should I use bound controls on the data entry/edit forms of my app or should I use unbound controls and copy the data manually from the controls to the dataset in response to say...an OK button OnClick event?
The advantage to using bound controls is obvious (especially in the case of using a bound grid control for the detail dataset in a master/detail relationship) in that much less coding is required.
However, I see some caveats to using bound controls.
As a simple example, lets say that I create a couple of tables for customer invoices. In the real world it would of course be a bit more complex than this, but this should illustrate my point.
I have the master table which hold the invoice info (customer, invoice number, etc.) and a detail table which holds the invoice line items (part no., description, price, unit of measure, etc.) in a grid control.
I quite often use an auto-increment field as the primary key of the master table and then use an INTEGER field as the foreign key in the detail table and set the link up as usual, with maybe a smallint field to number the line items, with the combination of the foreign key field and the line item field constituting the compound primary key of the detail table.
I also like to set up referential integrity between the auto-increment field in the master table and the foreign key INTEGER field in the detail table so as to prevent any possibility of orphaned records in the detail dataset. Of course you could enforce this in code, but it makes sense to have the MySQL server enforce this (thats what referential integrity is for!) since it would never make any sense to allow an invoice line item to exist that does not reference an invoice master record.
Now my user clicks on the "New Invoice" button in the application and up pops the invoice editing form with controls at the top of the form (text edits, checkboxes, etc.) linked to the MASTER table and a grid at the bottom of the form linked to the line items DETAIL table. Before the form displays, the MASTER table's Insert method is executed so all controls are empty, waiting for data input.
Now lets say my end user begins typing in the grid first. Remember, end users aren't necessarily thinking about the "order" in which they are to enter data, they just want to fill out the form and click the "OK" or "Save" button or whatever when they are finished and the data is saved.
The problem is, as soon as the user tries to enter a second record in the grid, the grid tries to post the data but an exception is raised because the MASTER table has not been posted yet, hence the auto-increment field does not have a value yet, and therefore the foreign key of the detail dataset does not have a value yet either.
A solution to this problem is to post the MASTER dataset record in the BeforePost event of the detail dataset but then, if there are fields in the master dataset that require a value and the user has not yet entered them, or there's some other type of data constraint, then another exception(s) is raised! Also, using cached updates doesn't help either because no auto-increment numbers are generated until Commit is executed (I think that's the case).
The best solution that I can see is to not use bound controls at all but instead use unbound controls and write all edits to the dataset(s) in the correct order in one try...except block contained in the OnClick event of "OK" or "Save" button and then raise any exceptions within the try...except block if user has omitted any required data or has any other data integrity violations.
Does anyone have any input on this?
Thanks.
JTW
The main point of my post is...should I use bound controls on the data entry/edit forms of my app or should I use unbound controls and copy the data manually from the controls to the dataset in response to say...an OK button OnClick event?
The advantage to using bound controls is obvious (especially in the case of using a bound grid control for the detail dataset in a master/detail relationship) in that much less coding is required.
However, I see some caveats to using bound controls.
As a simple example, lets say that I create a couple of tables for customer invoices. In the real world it would of course be a bit more complex than this, but this should illustrate my point.
I have the master table which hold the invoice info (customer, invoice number, etc.) and a detail table which holds the invoice line items (part no., description, price, unit of measure, etc.) in a grid control.
I quite often use an auto-increment field as the primary key of the master table and then use an INTEGER field as the foreign key in the detail table and set the link up as usual, with maybe a smallint field to number the line items, with the combination of the foreign key field and the line item field constituting the compound primary key of the detail table.
I also like to set up referential integrity between the auto-increment field in the master table and the foreign key INTEGER field in the detail table so as to prevent any possibility of orphaned records in the detail dataset. Of course you could enforce this in code, but it makes sense to have the MySQL server enforce this (thats what referential integrity is for!) since it would never make any sense to allow an invoice line item to exist that does not reference an invoice master record.
Now my user clicks on the "New Invoice" button in the application and up pops the invoice editing form with controls at the top of the form (text edits, checkboxes, etc.) linked to the MASTER table and a grid at the bottom of the form linked to the line items DETAIL table. Before the form displays, the MASTER table's Insert method is executed so all controls are empty, waiting for data input.
Now lets say my end user begins typing in the grid first. Remember, end users aren't necessarily thinking about the "order" in which they are to enter data, they just want to fill out the form and click the "OK" or "Save" button or whatever when they are finished and the data is saved.
The problem is, as soon as the user tries to enter a second record in the grid, the grid tries to post the data but an exception is raised because the MASTER table has not been posted yet, hence the auto-increment field does not have a value yet, and therefore the foreign key of the detail dataset does not have a value yet either.
A solution to this problem is to post the MASTER dataset record in the BeforePost event of the detail dataset but then, if there are fields in the master dataset that require a value and the user has not yet entered them, or there's some other type of data constraint, then another exception(s) is raised! Also, using cached updates doesn't help either because no auto-increment numbers are generated until Commit is executed (I think that's the case).
The best solution that I can see is to not use bound controls at all but instead use unbound controls and write all edits to the dataset(s) in the correct order in one try...except block contained in the OnClick event of "OK" or "Save" button and then raise any exceptions within the try...except block if user has omitted any required data or has any other data integrity violations.
Does anyone have any input on this?
Thanks.
JTW