Chapter Ten Windows Database Programming
Chapter Ten Windows Database Programming
Coverage:
This chapter teaches you to store data to and retrieve data from databases. The chapter focuses
on Microsoft Access and Microsoft SQL Server databases; however, the programming
techniques covered also work with other database management systems (DBMS) such as Oracle
Corporation's Oracle DBMS and Oracle databases. You will learn to display data in various
Windows-based controls such as TextBox and DataGridView controls.
The first form displays information from the Course table of the VBUniversity database
through use of a DataGridView control.
Table – basic database object that stores data – looks like a spreadsheet when you're
viewing data. This figure shows a Student table diagram from a Microsoft SQL Server
database.
Column = a column is a field of data stored for each course such as CourseID, Title,
Department, or for each student such as the StudentSSN, LastName, and FirstName.
Key Column (Field) – uniquely identifies a row in a table – almost all database tables
require one or more columns that form the key column(s) to identify rows uniquely –
eliminates the occurrence of duplicate rows.
Database Products – VB.NET stores and retrieves data for many different database products
including, but not limited to:
Oracle (by Oracle Corporation) and DB2 (by IBM) for large systems—these are
competing relational database management systems.
Microsoft SQL Server for mid-sized systems and larger scalable systems.
Microsoft Access and other small-sized, individual user or small group systems.
Entities and Relationships – a database stores data about individual entities in separate tables –
example university database entities include Students, Courses, Enrollment (the enrollment of
students in courses), and States.
This figure shows an entity-relationship diagram for tables in a Microsoft SQL Server
version of the VB University database.
Relationship – the lines connecting entities represent relationships between the rows in one
table and rows in another table.
One-to-many relationship – this is the relationship from rows in the Student table to
rows in the Enrollment table (there can be multiple enrollments by students in a course).
o The key symbol represents the one side of the relationship; the infinity symbol
represents the many side of the relationship.
o A student can have many enrollments, but an enrollment row belongs (is
associated) to only one student row.
o There are other kinds of relationships that you will study in your course on
database modeling and design.
Primary Key Columns –table rows are uniquely identified by one or more primary key
columns. Each table has a different primary key. In the above figure the primary key column
for the various tables are:
States table key = StateCode (2-character abbreviation for the state name).
Table Types
Base table – a base table is one that stores basic information about entities – examples
above are the Course and Student tables.
Validation table – a validation table validates data entered into another table. The
States table is used to validate the value of the StateCode column information entered
for a student row in the Student table.
ADO.NET
VB.NET uses ADO.NET (Active-X Data Objects with .NET technology), a database technology
that supports connection to different database products. ADO.NET:
Provides the application programming interface between the program application and the
Database Management System that manages the database. The current API is ADO.NET
4.
Stores and transfers data using the Extensible Markup Language (XML).
o OLEDB (Object Linking and Embedding Database) – used to connect to all other
database formats – this includes Microsoft Access DBMS.
ADO.NET supports database access using forms developed for either a Windows or
Web Form environment.
ADO.NET provides controls that you add to a form that are used to connect to and
manage data in a database table. Columns from a database table are bound to database
controls.
Controls you can bind include: Label, TextBox, and ComboBox controls as well as some
new controls such as the DataGridView control.
Connecting to a Database or Data Source with VB
This figure shows the steps in setting up a connection to a database or other type of data source.
Configure a binding source. The binding source links to a data source – a data source is usually
a specific database file, but can be another data source such as an array or text file.
Configure a table adapter. A table adapter handles data retrieval and updating. The table
adapter creates a dataset.
Create a dataset. A dataset stores data rows that have been retrieved.
Add controls to the form and set properties of the controls to bind the controls to the columns of
a specific table in the dataset.
The Microsoft Access database provider (the Microsoft.Jet.OLEDB.4.0 provider) is not available
in a 64-bit version -- it is only available as 32-bit.
This figure shows a data load failure exception for the Course Grid form that you will build
later in this note set. Also, the form will not display any data after you click the OK button.
The approach you take to fixing this problem depends on whether you are running Visual
Studio Ultimate Edition or the Visual Basic Express Edition.
Use this procedure if you are running Visual Studio Professional Edition. In order to connect to
an Access database when running Visual Studio on a 64-bit machine, you need to specify for
Visual Studio to use 32-bit mode. Follow these steps to eliminate this error:
1. Open Solution Explorer -- click on the My Project node to open the My Project window.
2. Click the Compile tab along the left side of My Project -- the figure shown below will
display.
3. Click the Advanced Compile Options... button to display the Advanced Compiler Settings
dialog box.
4. Click the Target CPU drop-down arrow and select the x86 target -- this will allow your program
to run in 32-bit mode.
Visual Basic Express Edition Fix
Use this procedure if you are running Visual Basic Express Edition. In order to connect to an
Access database when running Visual Studio on a 64-bit machine, you need to specify for Visual
Studio to use 32-bit mode; however, the above procedure will not work because the Advanced
Compiler Settings window will not display a Target CPU drop-down box. Instead, you will need
to carefully modify the project file using a text or XML editor.
1. With your VB application program open, select the File menu, Close Project option to close
the project and/or solution as shown in this figure.
4. After opening the file, it should display (open) in an XML editor window.
5. Locate the first <PropertyGroup> section and add the following line:
<PlatformTarget>x86</PlatformTarget>
6. Save the project (.vbproj) file. You can now reopen the project—use the File menu, Open
Project option to browse for the project folder and click the solution file (.sln) to open the project,
and continue with your debugging and testing.
FileName = CourseGrid.vb
Font – Size = 9
Displaying Data
3. Access the Data section of the Toolbox in design view. Add a DataGridView control from
the toolbox as shown here.
4. Click the smart arrow tag in the upper right-corner of the DataGridView control – this
displays the DataGridView Tasks window shown in the figure given above.
Dock property – you can select either the value Fill in the Properties window or click
the Dock in parent container link shown in the figure above – this will cause the control
to fill the form.
Choose Data Source – click the dropdown and select the Add Project Data Source…
hyperlink shown in the figure below – data sources can also be added with the Data
menu.
7. Data Source Configuration Wizard – the wizard displays the Choose a Data Source Type
window, select the Database as a data source type as shown in this figure, then click the Next
button.
8. Choose a Database Model window – click Dataset option and click the Next button.
9. Choose Your Data Connection window – click the New Connection button. Your software
may show an existing connection such as that shown in the figure below – it shows a connection
to a server named doug8400 (my home computer) – you want a new connection for this project
so ignore any existing connections.
10a. Either a Choose Data Source or an Add Connection window will open.
If a Choose Data Source window is displayed as shown in this figure, we will usually select the
Microsoft Access Database File option. Click Continue.
If the Add Connection window is open or if you wish to change the type of connection to be
created, then click the Change button. The default Data Source is Microsoft SQL Server
(SqlClient) as shown in the figure below – to add either a SQL Server Database file or MS
Access database file to your project as the data source, click the Change button.
NOTE: Usually in class we will change to a Microsoft Access Database File option. If you
are using Microsoft Access, skip to Step 11b.
The next figure shows the MS SQL Server Add Connection dialog box, click Browse –
locate the VBUniversity.mdf file you earlier copied to the My Documents location –
select it and click Open in the browse window – you will see the path and database file
name added to the Add Connection dialog box as shown in the figure below.
Click the Test Connection button – if the connection succeeds, you will see a popup
window telling you that the Test connection succeeded. Click OK to close the popup
and OK to close the Add Connection dialog box.
The next figure shows the Microsoft Access Add Connection dialog box, click Browse
– locate the VBUniversity.mdb file you earlier copied to the My Documents location –
select it and click Open in the browse window – you will see the path and database file
name added to the Add Connection dialog box as shown in the figure below.
The database logon will use the Admin user – no password is necessary for a MS Access
database.
Click the Test Connection button – if the connection succeeds, you will see a popup
window telling you that the Test connection succeeded. Click OK to close the popup
and OK to close the Add Connection dialog box.
12. Choose Your Data Connection dialog box – you are returned to this window after selecting
the database. Note that the name of the database file has been added to the window. This
window shows an Access database file. Click Next.
13. Visual Studio now asks if you would like the database file (local data file) added to the
project as shown in the Figure 10.13 below. Click Yes.
Clicking Yes causes the database file to copy to the project folder's root directory making
the project portable so you can take it back and forth to/from work/home/school – however, the
file is copied every time you run the project so any changes you make in terms of adding new
rows, modifying existing rows, or deleting rows will not be made permanently to the copy of the
file without making additional modifications to the properties of the database file – we will make
those changes after configuring the data source.
Clicking No causes the project to point (locate) the file based on the
ConnectionString property setting in its original position – a copy of the database
file is not made in the project.
14. Save the Connection String to the Application Configuration File – defaults to a
selection of Yes – saving the connection string to a configuration file will enable you to change
the string if necessary at a later point in time. Ensure the check box is checked, and then click
Next.
15. Choose Your Database Objects – VB retrieves information from the database file about
the tables and other database objects available for your use. This takes a few moments as shown
in this figure.
15 (continued). Choose Your Database Objects – you must specify the table(s) from which to
retrieve the data to be data displayed by the DataGridView control.
In this figure, the Tables node is expanded and the Course table is selected.
Check the Course table checkbox – an alternative is to expand the Course table node and
check just selected columns—not all columns need be selected if they are not needed by
the application user.
16. After the wizard closes, the DataGridView control now has column names from the Course
table as column headings. Also the system component tray displays BindingSource,
TableAdapter, and DataSet objects with names assigned by VB.
IMPORTANT NOTE: If the form does not display any data and/or you get an error message
The Microsoft.Jet.OLEDB.4.0 provider is not registered on the local machine shown in the
figure below, refer to the section Microsoft Access and Windows 7 Problems provided earlier
in these notes.
Copy to Output Directory property setting – you must change this property of the
VBUniversity.mdb or VBUniversity.mdf file as shown in the figure below.
Change from Copy always to Copy if newer – when you make data row changes
(inserts, edits, or deletes) during program execution, the changes will now be saved
because the copy in the \bin\Debug folder will be the newest copy of the database file
and the database file copy in the project root directory will not overwrite the database file
copy in the \bin\Debug folder.
Fill method – the table adapter’s Fill method executes the SQL statement (it is a
SQL SELECT statement) that is stored in the table adapter. This fills the data set
object with data from the Course table.
VB generates the code automatically, but you can modify the code as necessary.
Me.CourseTableAdapter.Fill(Me.CourseGridDataSet.Course)
End Sub
Modify the Load event – add a Try-Catch block to handle situations where a
network connection fails.
Try
'Load Course table
Me.CourseTableAdapter.Fill(Me.CourseGridDataSet.Course)
Catch ex As Exception
MessageBox.Show(MessageString, TitleString,
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
1. Smart Tag – click the DataGridView control's Smart Tag arrow to display the
DataGridView Tasks window shown in the figure below – click the Edit Columns link as
shown in this figure.
3. CourseID Column – set the HeaderText property = Course ID (added a blank space for
readability). DO NOT CHANGE the DataPropertyName property by mistake.
4. Title Column.
Width property – change to 300 pixels – on startup the column will now display the
entire Title column value.
6. Modify the AutoSizeMode from Not Set to None and Width property to 75 pixels for the
CreditHours , Tuition, and CourseFees columns. Click OK to close the Edit Columns dialog
box.
This will cause all column sizes to vary to match the data displayed.
Individual columns that have the AutoSizeMode property changed from Not Set to
None and the Width property set to a specific width will retain the specified width – this
will override the DataGridView control’s AutoSizeColumnsMode property setting.
Close the Edit Columns window. In the Properties window access the
AutoSizeColumnsMode property of the DataGridView control and set the property to
AllCells.
DefaultCellStyle property – click the dialog button (… button) for this property to open
the CellStyle Builder window.
Format property – click dialog button (… button) for this property to display the
Format String Dialog window – Select Numeric with 2 Decimal places.
9. Repeat the steps for this column as you did in step 8 for the Tuition and CourseFees
columns.
10. Click OK to close the Edit Columns dialog box. Test the project – make any additional
changes needed in order to achieve a satisfactory display of data. Stop debugging when you
finish testing.
4. Click the smart arrow tag of the DataGridView control to display the DataGridView Tasks
window.
Enable column reordering, but disable adding, editing, and deleting data rows.
5. Choose a data source – use the existing data connection when the wizard displays the
Choose Your Data Connection dialog box.
Work through the wizard. In the Choose Your Database Objects dialog box select the Student
table.
Click Finish – when the wizard closes, observe the new objects in the system component tray
and the columns displayed in the DataGridView control.
6. Resize the form to make it large enough to display most of the data columns.
7. Open the coding window for the form and modify the Load event to add a Try-Catch block
like the one shown here.
Private Sub StudentGrid_Load(ByVal sender As System.Object,
ByVal e As System.EventArgs) Handles MyBase.Load
Try
Me.StudentTableAdapter.Fill(Me.StudentGridDataSet.Student)
Catch ex As Exception
MessageBox.Show(MessageString, TitleString,
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
9. Click the smart arrow tag to open the Edit Columns link. Use the Edit Columns dialog box
to:
Set the HeaderText property – change selected columns to the values indicated:
o StudentSSN – SSN
o MiddleInitial – Mi
o StateCode – State
o ZipCode – Zip
o PhoneNumber – Telephone
o EmailAddress – Email
Reorder the first three columns to be SSN, Last Name, and First Name (Select LastName
and use the Up/Down arrows).
Click My Project.
Close My Project.
Run the project. Check the display of all column data. Adjust any column widths as
necessary with the individual column’s AutoSizeMode and Width properties in the
Edit Columns window.
The form can be designed through use of the Data Sources window – set the data source
to display and drag the data table to the form.
Data Sources window – access by selecting the Data menu, Show Data Sources menu
item or from the Data Sources tab in the Solution Explorer.
Can be used to add a new data source to a project.
You will learn how to build a third form for the project like the one shown here.
2. Font Size and Bold properties – set as desired (the figure has a 9 point font with Bold =
True).
You should see the existing CourseGridDataSet and StudentGridDataSet data sources.
For existing data sources, the dataset(s) will display in the Data Sources window as in
this figure along with any tables or views stored in the dataset.
5. Add New Data Source – add a new data source for this form.
Click the icon shown in this figure (or use the Data menu, Add New Data Source menu
option).
Choose a Database Model dialog box – click Dataset and then Next.
Choose Your Data Connection dialog box – click Next to use the existing connection.
Choose Your Database Objects dialog box – expand the Tables node as shown in the
figure below – checkmark the Student table – name the dataset object
StudentDetailsDataSet – click Finish.
Adding Bound Controls to the Form
You are ready to add bound controls to the form. You will use a drag/drop approach to build the
form – this is really fast and easy to use. If you mess it up, just delete the form and start over.
Select the drop-down arrow by the Student table and select Details (if the drop-down
arrow does not display, ensure that the form view for design mode is displayed – not the
coding view).
Note that the icon for a Details view is different than that for a DataGridView.
8. Point at the Student table name in the Data Sources window – drag/drop the table to the
StudentDetails form to a position about an inch from the top and left margins of the form – the
form will automatically have Label and TextBox controls generated and displayed for each
column in the Student table as shown in this figure.
Note the following:
The labels have the Text property setting generated automatically by VB – the column
names are automatically divided into prompts appropriate for the form.
Note the new components that were automatically added to the system component tray:
o StudentDetailsDataSet
o StudentBindingSource
o StudentTableAdapter
o TableAdapterManager
2. Move buttons (Move first and Move previous are grayed out in the
figure) such as the Move next button highlighted in the figure next to
the Move last button.
9. Alter the layout by drag/drop the controls on the form as shown in the figure below.
Reorder the name to display Last Name, then First Name, then Middle Initial.
Change the labels as shown on the figure for the Middle Initial (to M), City, State Code,
and Zip Code (to City/State/Zip) and Phone Number (to Phone).
Tab order – reset to reflect the new arrangement to tab from left-to-right, top-to-bottom.
In the Application tab change the Startup Form property setting to the StudentDetails
form.
Note the telephone textbox and account balance textbox controls do not display
formatted.
Navigation buttons – test the ability to navigate from row to row. Note the display of
data as you navigate from row to row
The form enables you to alter the dataset in memory, and will save changes to the
database.
o Practice saving a row of data – click the Add button, enter the data, and click the
Save button.
o Shutdown and then run the project again – locate the new data row.
o Try adding a duplicate row (with Student SSN = 111-11-1111) – note that the
system generates an ConstraintException was unhandled error message when
the Save button is clicked.
o Try to delete a data row (with Student SSN = 111-11-1111) – note that the system
generates an OleDBException was unhandled error message when the Save
button is clicked – this is because the Student table data row is related to data
row(s) in the Enrollment table (the exception generated depends on whether you
are using a Microsoft Access or Sql Server database).
These problems are addressed later in this note set by writing additional program code.
The code generated by VB for the StudentGrid form’s Load event needs to be modified by
adding a Try-Catch block to catch exceptions as was done earlier for the Student form.
Try
Me.StudentTableAdapter.Fill(Me.StudentDetailsDataSet.Student)
Catch ex As Exception
MessageBox.Show(MessageString, TitleString,
MessageBoxButtons.OK, MessageBoxIcon.Error)
End Try
End Sub
Sorting Data
The data displayed in the form is not sorted.
There are several ways to change the sorted display of data. This describes one approach.
2. In the Properties window select the Sort property – type the name of the column or columns
to be used to sort data in the dataset – the column name(s) entered must EXACTLY match those
in the dataset.
The figure below shows sorting by LastName and then FirstName column name values.
Enter the property value as LastName, FirstName – do not forget the comma between
the column names.
3. Run the project and confirm that the data is sorted by last name and then first name within
last name.
The new MaskedTextBox will not display any data because the control is not bound to the
DataSource.
Select the Text property – Use the drop-down arrow for this property to select the
StudentBindingSource, and then select the PhoneNumber column – this will bind the
Text property so that it will display data from the PhoneNumber column of the
StudentBindingSource object to the MaskedTextBox control as shown in the figure
below.
Navigate from row to row with the buttons and note how the form appears when the
student has no telephone number recorded in the database.
1. Replace the student SSN and the zip code TextBox controls with MaskedTextBox controls.
o SSNMaskedTextBox.
o ZipMaskedTextBox.
Some tables have data columns that represent numeric output such as the student
AccountBalance column.
SQL Server stores the data with four digits to the right of the decimal point so simply
displaying the data to a TextBox results in a display that application users may find
confusing.
Neither SQL Server nor MS Access displays numeric data formatted as currency or
numeric with appropriate currency symbols, commas, and the correct number of digits to
the right of the decimal point.
Binding – ensure the correct database table field is bound – here the AccountBalance is
bound.
The default configuration enables an application user to modify any data row, but does
not provide a means to enforce saving changes when they are made.
The Save button provided by default will save changes, but there is no way to ensure the
application user clicks Save other than through the Form's Closing event.
Using the Form's Closing event to save changes can result in an attempt to save multiple
changes at the same time, but some of these may violate database integrity rules, such
as the length of a data value or the type of data to be saved from a TextBox or other
bound control. This can cause the save event code to ABEND.
The approach you will learn here changes the default configuration as follows:
Make Bound Controls ReadOnly – each bound control on the form will have
ReadOnly = True – this will prevent changing any data row values.
Add an Edit Button – edit operations will begin by having the application user click an
Edit Button on the BindingNavigator control – since there is no Edit Button on the
control, one will need to be added.
Add a Cancel Button – a Cancel Button will need to be added to the BindingNavigator
control in the event that the application user decides not to edit a data row or clicks the
Edit Button by accident.
Disable Cancel and Save Buttons – both of these buttons needs to be disabled while
viewing records – their Enabled property = False; during Add and Edit operations set
Enabled = True for both of these buttons.
Alter the BindingNavigator Control Interface – during Edit operations, all items on
the BindingNavigator control except the Save and Cancel Buttons will be disabled by
making them invisible – set Visible = False.
When the operation is either saved or canceled, the values of ReadOnly and Visible will
be reversed.
Set ReadOnly = True for all TextBox and MaskedTextBox controls that display data.
Notice that the background color of the controls changes from white to light blue or gray.
Click the Add ToolStripButton drop-down on the control and select a Button to be
added as shown in this figure. This adds a ToolStripButton.
Right-click the EditToolStripButton button (the default image is a mountain with the
sun shining) and either set the Image property to an appropriate image or switch the
DisplayStyle property to Text – we will use an image.
Images are available on drive Y: for the Chapter 10 project.
o Click the dialog button ( … ) to open the Select Resource dialog box shown in the
figure below – click the Import button and navigate to the directory that stores
class image files – select the image file named edit-48x48.png (as shown in the
figure).
If you use Text instead of an image, set the Text property = Edit.
Set the DisplayStyle property = Image and import the image file named x-48x48.png.
This sub procedure will set ReadOnly = False for the bound controls that display data
row values.
'operations
SSNMaskedTextBox.ReadOnly = ValueBoolean
LastNameTextBox.ReadOnly = ValueBoolean
FirstNameTextBox.ReadOnly = ValueBoolean
MiddleInitialTextBox.ReadOnly = ValueBoolean
AddressTextBox.ReadOnly = ValueBoolean
CityTextBox.ReadOnly = ValueBoolean
StateCodeTextBox.ReadOnly = ValueBoolean
ZipMaskedTextBox.ReadOnly = ValueBoolean
PhoneMaskedTextBox.ReadOnly = ValueBoolean
EmailAddressTextBox.ReadOnly = ValueBoolean
MajorTextBox.ReadOnly = ValueBoolean
AccountBalanceTextBox.ReadOnly = ValueBoolean
BindingNavigatorMoveFirstItem.Visible = ValueBoolean
BindingNavigatorMoveLastItem.Visible = ValueBoolean
BindingNavigatorMoveNextItem.Visible = ValueBoolean
BindingNavigatorMovePreviousItem.Visible = ValueBoolean
BindingNavigatorPositionItem.Visible = ValueBoolean
BindingNavigatorCountItem.Visible = ValueBoolean
BindingNavigatorAddNewItem.Visible = ValueBoolean
BindingNavigatorDeleteItem.Visible = ValueBoolean
EditToolStripButton.Visible = ValueBoolean
StudentBindingNavigatorSaveItem.Enabled = Not
ValueBoolean
End Sub
Add this sub procedure to your program. Check that the control names on your form match the
names used in the sub procedure.
Makes the TextBox and MaskedTextBox controls ReadOnly = False so the data can be
altered.
Makes the BindingNavigator control’s Move, Position and Buttons (except Cancel and
Save) invisible.
SetControls(False)
End Sub
Add this sub procedure to your program. Check that the control names on your form match the
names used in the sub procedure.
1. CancelEdit method – use this method of the BindingSource control to "throw away" any
changes that may have been made to the current data row.
Application users may wish to cancel when they accidentally click Edit or Add.
They may also wish to click cancel when they change their mind about editing a record.
2. SetControls – call this sub procedure with a value of True to make the form's bound controls
ReadOnly again and to make the BindingNavigator control's buttons visible.
StudentBindingSource.CancelEdit()
SetControls(True)
End Sub
Run the project to ensure that the form starts up with all BindingNavigator controls
visible and enabled except for the Save and Cancel Button controls.
Click Edit – the form should now enable editing with only the Save and Cancel Button
controls visible on the BindingNavigator.
Change a record and click Cancel – the change should be "thrown away" and the form
will be restored to its original configuration.
Before you can save any changes, you need to modify the Save Button code—the next
section explains Data Row Save Operations.
Visual Studio adds a Save Button to the BindingNavigator when the TableAdapter is
generated when you drag the table onto the form.
If you add a BindingNavigator control to a form, you will not see a Save Button and
will need to add one.
The code generated by VB for the Save button of the binding navigator control is very simple
and does not catch exceptions. The code is shown here.
Me.Validate()
Me.StudentBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.StudentDetailsDataSet)
End Sub
The Validate method for the form confirms that any Validating event sub procedures
have validated data on the form – on this project you will not use any Validating event
sub procedures so this line of code has no purpose for your program – this line of code
can be deleted or converted to a remark in case it is needed later.
The EndEdit method of the StudentBindingSource object ends all edit operations. This
applies to both updates of existing data rows and the addition of new data rows.
The UpdateAll method of the TableAdapterManager control causes a reconnection to
the database and updates any modifications of StudentDetailsDataSet.
It is also necessary to call the SetControls sub procedure to reestablish the user interface
on the form following a successful save.
Try
'Me.Validate()
Me.StudentBindingSource.EndEdit()
Me.TableAdapterManager.UpdateAll(Me.StudentDetailsDataSet)
Me.SetControls(True)
Catch ex As Exception
End Try
End Sub
The UpdateAll method is fairly complex and is more useful than the older Update method that
was previously used to update datasets.
Updates are performed on a row-by-row basis – this means that if multiple DataSet
modifications (either Insert, Update, or Delete operations), then you would need to
control the order of the updates.
Using the TableAdapterManager ensures that updates involving multiple tables are
processed in the correct order where the order of the updates is important.
The code you're learning in this note set only allows a single update operation to take
place at a time – if the database rejects the update, then it is easier to handle the
OleDbException that is thrown by the database back to your application with a Try-
Catch block.
When an UpdateAll method fires, the TableAdapterManager examines each data row's
RowState property in order to execute the required INSERT, UPDATE, or DELETE
statements.
After a successful update, changes to the data row are accepted within the DataSet – this
makes it unnecessary to call the AcceptChanges method of the DataSet object.
Run the project, select a data row to edit, and click the Edit Button.
Make a change to the data (such as the student's Major field of study) and click the Save
button.
Shutdown the application, then start it back up again – you should find that the data row
was saved with the new data value.
Clicks the Add New button to add a second new record before the first Add operation is
finished.
Clicks one of the Move buttons – this triggers an Update of the dataset even though the
new record isn't complete.
Calling the SetControls sub procedure with a value of False will ensure that neither of the above
conditions can occur because during an Add Operation the Add New button and all Move
buttons are invisible.
Display the form with "empty" controls to allow entry of a new student record – this is
accomplished by the application user clicking the Add New Button on the
BindingNavigator control – this requires NO coding on your part as the AddNew
method is automatically called by clicking the Add New Button
Once an Add operation begins, the application user must only be able to click Save or
Cancel. Calling SetControls accomplishes this.
When an Add operation is finished, the application user clicks either Save or Cancel.
SetControls – the click event sub procedure calls the SetControls sub procedure to
disable some of the binding navigator controls.
Focus method – this method sets focus to the SSNMaskedTextBox to make it easy for
the application user to begin to enter new row data.
Private Sub BindingNavigatorAddNewItem_Click(ByVal sender As
System.Object, ByVal e As System.EventArgs) Handles
BindingNavigatorAddNewItem.Click
SetControls(False)
'Set focus
SSNMaskedTextBox.Focus()
End Sub
Click the Add Button – add a new data row for yourself as a student.
Try to add a second data row that has a duplicate SSN value of 111-11-1111 – clicking
Save should cause the data row to be rejected because it would be a duplicate student
row.
Clicking Cancel should "throw away" the new duplicate data row.
Sounds simple, but by the time the code that you write for the Button's Click event
executes, the BindingNavigator has already called the RemoveCurrent method for the
BindingSource object and there is no simple way to cancel the action.
Try
If ResponseDialogResult =
Windows.Forms.DialogResult.Yes Then
StudentBindingSource.RemoveCurrent()
StudentBindingSource.EndEdit()
TableAdapterManager.UpdateAll(StudentDetailsDataSet)
End If
StudentDetailsDataSet.RejectChanges()
StudentBindingSource.Position = RowNumberInteger
Catch ex As Exception
End Try
End Sub
Assume that the delete operation may fail – it will be necessary to restore the dataset and
redisplay the deleted record. The first line of code saves the record number of the data
row to be deleted.
If the application user responds to delete the row, the value of ResponseDialogResult is
checked. If it is "Yes", then:
StudentTableAdapter.Update(StudentDetailsDataSet.Student)
If the deletion fails, the line of code generating the exception will usually be the line of code
with the UpdateAll method. This triggers an OleDbException that is caught by the first of two
Catch blocks. The OleDbException is raised when a deletion fails due to referential integrity
constraints:
o The DataSet's RejectChanges method is used to reject the deletion in the DataSet
– essentially this undeletes the deleted row that the database rejected.
o The BindingSource's Position property is reset to the record number of the data
row for which deletion failed.
A DataSet's RejectChanges method rolls back all DataSet changes made since the DataSet was
created, or since the last execution of DataSet.AcceptChanges.
Each DataRow's RowState property changes – Added and Modified rows become
Unchanged, and Deleted rows are removed from the DataSet.
However, it is not necessary to code a call of the AcceptChanges method because the
UpdateAll method automatically does this for you as the programmer.
Data Validation
Additional Exception Handling
A program can be improved through the use of techniques to ensure data values entered during
Edit and Add operations are valid.
You have learned to use a ValidData function to validate data entry
This chapter also requires you to write a ValidData function to validate data. A good
practice is to use a ValidData function to validate data entered for a new record or
modified for an existing record prior to executing an UpdateAll method to modify the
database.
You can replace the Me.Validate command generated for a Save button with the
BindingNavigator control with a call to a ValidData function.
ValidData Function
The function shown here enforces four different types of validation rules:
Missing data – data cannot be missing from a bound control if the corresponding field in
the database table requires stores of data, i.e., required data.
LastNameTextBox
FirstNameTextBox
AddressTextBox
CityTextBox
StateCodeTextBox
MiddleInitialTextBox
PhoneMaskedTextBox
EmailAddressTextBox
MajorTextBox
AccountBalanceTextBox
Data cannot contain blank spaces – data fields such as the SSN and Zip Code cannot
contain blank spaces. The IndexOf method can test for the existence of any character (in
this case a blank space) within a specified portion of a string. You must validate that the
SSN contains no blank spaces. You must also validate that the Zip Code contains no
blank spaces within the first five characters – the last four characters of a zip code can be
blank.
Data must be a specific length – data fields such as a SSN must be a specific length—
here that length includes storage of the dash "-" symbol so the field length is 11
characters. The SSNMaskedTextBox box control is tested for the reasonableness of the
data – a rule is enforced requiring the number of digits and dash symbols entered must be
exactly 11 digits by using the Length method – this method returns the number of
characters in a data string.
Initially the code sets the function name ValidData = False – this assumes that some of the data
is not valid.
If a rule fails, an error message is displayed and control passes to the End If at the
bottom of the function and the function exits returning a value of False. This approach
ensures that only one error message at a time will display.
If all business rules are satisfied, the Else branch executes setting ValidData = True and
the function exits returning a value of True.
Note the use of Focus and SelectAll methods to make the program more user-friendly.
ValidData = False
SSNMaskedTextBox.Focus()
SSNMaskedTextBox.SelectAll()
SSNMaskedTextBox.Focus()
SSNMaskedTextBox.SelectAll()
LastNameTextBox.Focus()
LastNameTextBox.SelectAll()
FirstNameTextBox.SelectAll()
'Validate Address
AddressTextBox.Focus()
AddressTextBox.SelectAll()
'Validate City
CityTextBox.Focus()
CityTextBox.SelectAll()
'Validate State
StateCodeTextBox.Focus()
ZipMaskedTextBox.Focus()