Exploring the DataAdapter and DataTable Events
You'll find all the code examples shown in this section in the program UsingEvents.cs
located in the ch11 directory. The listing for this program is omitted from this book for
brevity. If you compile and run that program, you'll see the order in which the events fire
when you add, modify, and remove a row from a DataTable that contains rows retrieved
from the Customers table.
The DataAdapter Events
The events exposed by a SqlDataAdapter object are shown in Table 11.11
.
Table 11.11: SqlDataAdapter EVENTS
EVENT EVENT HANDLER DESCRIPTION
FillError FillErrorEventHandler Fires when an error occurs during a call to the
Fill() method.
RowUpdating RowUpdatingEventHandler Fires before a row is added, modified, or
deleted in the database as a result of calling
the Update() method.
RowUpdated RowUpdatedEventHandler Fires after a row is added, modified, or
deleted in the database as a result of calling
the Update() method.
The FillError Event
The FillError event fires when you call the Fill() method and an error occurred. The
following are a couple of scenarios that would cause an error:
•
An attempt is made to add a number from the database to a DataColumn that
couldn't be converted to the .NET type of that DataColumn without losing
precision.
•
An attempt is made to add a row from the database to a DataTable that violates a
constraint in that DataTable.
The following example event handler, named FillErrorEventHandler(), checks for the
precision conversion error:
public static void FillErrorEventHandler(
object sender, FillErrorEventArgs myFEEA
)
{
if (myFEEA.Errors.GetType() == typeof(System.OverflowException))
{
Console.WriteLine("A loss of precision occurred");
myFEEA.Continue = true;
}
}
The first parameter is an object of the System.Object class, and it represents the object
that raises the event. The second parameter is an object of the FillErrorEventArgs class,
which like all the EventArgs classes, is derived from the System.EventArgs class. The
EventArgs class is the base class for event data and represents the details of the event.
Table 11.12
shows the FillErrorEventArgs properties.
Table 11.12: FillErrorEventArgs PROPERTIES
PROPERTY TYPE DESCRIPTION
Continue bool Gets or sets a bool that indicates whether you want to continue
filling your DataSet even though an error has occurred. The
default is false.
DataTable DataTable Gets the DataTable that was being filled when the error
occurred.
Errors Exception Gets the Exception containing the error that occurred.
Values object[] Gets the DataColumn values of the DataRow in which the error
occurred. These values are returned in an object array.
You indicate that mySqlDataAdapter is to call the FillErrorEventHandler() method when
the FillError event fires using the following code:
mySqlDataAdapter.FillError +=
new FillErrorEventHandler(FillErrorEventHandler);
The RowUpdating Event
The RowUpdating event fires before a row is updated in the database as a result of you
calling the Update() method of your DataAdapter. This event fires once for each
DataRow you've added, modified, or deleted in a DataTable.
The following actions are performed behind the scenes for each DataRow when you call
the Update() method of your DataAdapter:
1. The values in your DataRow are copied to the parameter values of the appropriate
Command in the InsertCommand, UpdateCommand, or DeleteCommand property
of your DataAdapter.
2. The RowUpdating event of your DataAdapter fires.
3. The Command is run to push the change to the database.
4. Any output parameters from the Command are returned.
5. The RowUpdated event of your DataAdapter fires.
6. The AcceptChanges() method of your DataRow is called.
The second parameter to any event handler method you write to handle the RowUpdating
event of a SqlDataAdapter object is of the SqlRowUpdatingEventArgs class, and Table
11.13 shows the properties of this class.
Table 11.13: SqlRowUpdatingEventArgs PROPERTIES
PROPERTY TYPE DESCRIPTION
Command SqlCommand Gets or sets the SqlCommand that is run when the
Update() method is called.
Errors Exception Gets the Exception for any error that occurred.
Row DataRow Gets the DataRow to send to the database through
the Update() method.
StatementType StatementType Gets the type of the SQL statement that is to be run.
StatementType is an enumeration in the System.Data
namespace that contains the following members:
•
Delete
•
Insert
•
Select
•
Update
Status UpdateStatus Gets or sets the UpdateStatus of the Command
object. UpdateStatus is an enumeration in the
System.Data namespace that contains the following
members:
•
Continue, which indicates that the
DataAdapter is to continue processing rows.
•
ErrorsOccurred, which indicates that the
update is to be treated as an error.
•
SkipAllRemainingRows, which indicates that
the current row and all remaining rows are to
be skipped and not updated.
Table 11.13: SqlRowUpdatingEventArgs PROPERTIES
PROPERTY TYPE DESCRIPTION
•
SkipCurrentRow, which indicates that the
current row is to be skipped and not updated.
The default is Continue.
TableMapping DataTableMapping Gets the DataTableMapping object that is sent to the
Update() method. A DataTableMapping object
contains a description of a mapped relationship
between a source table and a DataTable (see Chapter
10, "Using DataSet Objects to Store Data").
The following example event handler, named RowUpdatingEventHandler(), prevents any
new rows from being added to the database with a CustomerID of J5COM:
public static void RowUpdatingEventHandler(
object sender, SqlRowUpdatingEventArgs mySRUEA
)
{
Console.WriteLine("\nIn RowUpdatingEventHandler()");
if ((mySRUEA.StatementType == StatementType.Insert) &&
(mySRUEA.Row["CustomerID"] == "J5COM"))
{
Console.WriteLine("Skipping current row");
mySRUEA.Status = UpdateStatus.SkipCurrentRow;
}
}
You indicate that mySqlDataAdapter is to call the RowUpdatingEventHandler() method
when the RowUpdating event fires using the following code:
mySqlDataAdapter.RowUpdating +=
new SqlRowUpdatingEventHandler(RowUpdatingEventHandler);
If you then call the AddDataRow() method shown earlier to attempt to add a row to the
Customers table, the RowUpdating event will fire and call the
RowUpdatingEventHandler() method. This method causes the new row to be skipped and
prevents it from being added to the Customers database table.
The RowUpdated Event
The RowUpdated event fires after a row is updated in the database as a result of you
calling the Update() method of your DataAdapter. This event fires once for each
DataRow you've added, modified, or deleted in a DataTable.
The second parameter to any method you write to handle the RowUpdated event of a
SqlDataAdapter object is of the SqlRowUpdatedEventArgs class. The properties of this
class are the same as those shown earlier in Table 11.13
, plus one additional property
shown in Table 11.14
.
Table 11.14: ADDITIONAL SqlRowUpdatedEventArgs PROPERTY
PROPERTY TYPE DESCRIPTION
RecordsAffected int Gets an int containing the number of rows added, modified, or
removed when the appropriate Command is run by the Update()
method.
The following example event handler, named RowUpdatedEventHandler(), displays the
number of records affected by the following Command:
public static void RowUpdatedEventHandler(
object sender, SqlRowUpdatedEventArgs mySRUEA
)
{
Console.WriteLine("\nIn RowUpdatedEventHandler()");
Console.WriteLine("mySRUEA.RecordsAffected = " +
mySRUEA.RecordsAffected);
}
You indicate that mySqlDataAdapter is to call the RowUpdatedEventHandler() method
when the RowUpdated event fires using the following code:
mySqlDataAdapter.RowUpdated +=
new SqlRowUpdatedEventHandler(RowUpdatedEventHandler);
The DataTable Events
The events exposed by a DataTable object are shown in Table 11.15
.
Table 11.15: DataTable EVENTS
EVENT EVENT HANDLER DESCRIPTION
ColumnChanging DataColumnChangeEventHandler Fires before a changed