DataGrid Identity Increment Conflicts with MS SQL Server - The identity incremental feature of the DataGrid control conflicts with MS SQL Server when hosting a DataSet with an identity column. Learn how to fix this.
The LBTT Spot
"Lifeline is focused on developing and marketing systems designed to assist in the early detection of breast and ovarian cancer."



DataGrid Identity Increment Conflicts with MS SQL Server

View C# Source Code

Article Categories:

.Net Framework
.Net Framework 1.1
ADO.NET
ASP.NET
Assemblies
Asynchronous Methods
C#
Collections
Configuration
Delegates
Events
Pocket PC
Regular Expressions
Smart Devices
SQL Server
Visual C#
Visual Studio .NET
Visual Studio .NET 2003
Windows Forms
XML

C# .Net Fun Menu

View Current Page's ASP.NET Source Code
C# Reference
C# Study Flash Cards
Valuable Links
Contact Us
Site Map
Mike's Portfolio

C# Reference Search:

Full Text Search:

Articles by Author:

Code Examples (zipped):

DataGrid Identity Increment Conflicts with MS SQL Server

The identity incremental feature of the DataGrid control conflicts with MS SQL Server when hosting a DataSet with an identity column. Learn how to fix this.
Category: Windows Forms, ADO.NET, SQL Server, Visual Studio .NET, Posted 6/15/2003, By Mike G.

This article may help you if you are building Windows Forms applications that meet all of the following criteria:
  • An MS SQL Server (or MSDE) database table with an Identity column.
  • A DataGrid control.
  • A DataSet with an Identity column in a given table.
  • The DataGrid uses the DataSet as it's DataSource.
  • An SqlDataAdapter component used to manipulate the data stored in the MS SQL Server table.
Identity values maintained by a DataGrid hosting a DataSet object are local and do not derive from those identity values generated by the data store - in this case, MS SQL Server.



In the example above, if you click on the new record at the bottom of the DataGrid a new identity is automatically generated by the control for this record. If you don't end up creating the record by filling in data in the TestText column then navigating out of the record the next identity value is used for when you do end up creating a new record in the grid. This can be a problem since identity values generated by the DataGrid do not conincide with those generated by MS SQL Server.



If you use an SqlDataAdapter to update the data in the DataGrid then an INSERT statement is automatically generated for you by default. After the INSERT statement occurs a proceeding SELECT is used to retrieve a 'refreshed' version of the record from the MS SQL Server database. Now, if the SqlDataAdapterInsertCommand's UpdateRowSource is so to Both or FirstReturnedRecord the is is assumed that the values in the DataRow affected by the INSERT should be automatically updated - this does not happen!

It is up to you to update the affected DataRow yourself. A DataRow typically contains two versions of the row after a an INSERT statement is performed against it: Original and Current.
DataGrid Identity Conflict with MS SQL Server

As you can see by the image above, after hitting the Save button the SqlDataAdapter send the INSERT statement to MS SQL Server then retrieves an updated version of the record from the database via a SELECT statement. The correct ID is retrived from the database (26) but as you can see it doesn't appear in the DataGrid - the original value is still there! Eventhough the correctly retrieved identity value is set to the Current version of the DataRow it is not so in the DataGrid.

The Current version contains the correct value. The Original version does not. The DataGrid cell objects bind to the Original version of the DataRow object.

So, the key is to update the DataRow's TestID column, in this example, to the correct value so we can see it in the DataGrid control. To do that we need to create an SqlDataAdapter RowUpdated event handler and update the Original version value to that of the Current value like this:
private void sqlDataAdapter1_RowUpdated(object sender, System.Data.SqlClient.SqlRowUpdatedEventArgs e) { if (e.Row.HasVersion(DataRowVersion.Original) && e.Row.HasVersion(DataRowVersion.Current) && e.Row.RowState != DataRowState.Deleted) { dsDataSetIdentityProblemTest1.tblTest.FindByTestID( int.Parse(e.Row[0, DataRowVersion.Original].ToString())).TestID = int.Parse(e.Row[0, DataRowVersion.Current].ToString()); } } NOTE: in order for you to be able to update an identity value you must ensure that the identity column's readonly property is set to false.

Once that is done, the DataGrid will reflect the correct identity values!