Using a Dataset for datasource updates

It took me a while to figure this one out, but I got it.  I now have a piece of code that allows me to databind a dataset to controls on a client.  The client can then modify the dataset and the changes are persisted back to the datasource without using any config files or external files to describe the stored procedure being used (required paramters, param types, values, etc.). 

I am using stored procs for my updates.  The learning curve for me was figuring out how to build my sqlparameter types for the sproc calls.  I had to figure out how to:

1- grab only those DataColumns that were modified by the client and build a sqlparamter for each

2- determine the primary keys and build those sqlparameters

I grab the primary keys by setting

MissingSchemaAction = MissingSchemaAction.AddWithKey

on the data adapter fill call.  This returns an array of primary key datacolumns.  I store the array in a Property call 'PrimaryKeys'. Then, I add code to the dataadapter's OnRowUpfdating event to build my sqlparamter types.  I check to see if this is an update.  I then loop through the columns in the row to find the ones that have been modified.  I build a sqlparamter for each.  I then loop through my PrimaryKeys arrary and set each primary key.  Wala, that is it! 

Now, at runtime I know the dataSet Table primary keys, I know the modifed DataColumns and I can call dataadapter.update using a stored procedure for the update. 

Private Shared Property PrimaryKeys() As DataColumn()
        Get
            Return _primaryKeys
        End Get
        Set(ByVal Value As DataColumn())
            _primaryKeys = Value
        End Set
End Property

Protected Shared Sub OnRowUpdating(ByVal sender As Object, ByVal e As SqlRowUpdatingEventArgs)

    If e.StatementType = StatementType.Update Then

        Dim drw As DataRow = e.Row
        Dim col As DataColumn

        ' build a sqlparamter for each modifed column     

           For Each col In drw.Table.Columns
                If col.ColumnName <> "timestamp_column" Then
                    If drw(col, DataRowVersion.Current) <> drw(col, DataRowVersion.Original) Then
                        Dim myParam As New SqlParameter("@" & col.ColumnName, drw.Item(col).ToString)
                        e.Command.Parameters.Add(myParam)
                    End If
                End If
            Next

        ' build a sqlparameter for each primary key column

            For Each col In PrimaryKeys
                Dim myParam As New SqlParameter("@" & col.ColumnName, drw.Item(col).ToString)
                e.Command.Parameters.Add(myParam)
            Next

        End If

    End Sub

    

 

 

No Comments