Ok I have been trying to handle some of the concurrency errors on my winforms app. When the database record has changed and the user tries to save it gives a popup with a choice to overwrite or cancel basically.
My problem is if the record was deleted by another user and they try to save changes to it I get this error...
This is what I have for my saving code right now. In the Save() function I tried to catch that NullException and just tell the user that record has already been deleted by another user, but it doesn't work.
I have a save button that runs this code...
Then the Save() Function that runs this code...Code:Private Sub PordersBindingNavigatorSaveItem_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles PordersBindingNavigatorSaveItem.Click Me.Validate() Me.PordersBindingSource.EndEdit() Me.ItemsBindingSource.EndEdit() Me.PoinvoiceBindingSource.EndEdit() If Me.Save() Then MsgBox("Your purchase order changes were saved.") End If End Sub
These subs are for when it runs the UpdateDatabasePorders. They look basically the same for UpdateDatabaseItems and UpdateDatabaseInvoice.Code:Private Function Save() As Boolean Dim saved As Boolean = False If Me.PordersItemsDataSet.HasChanges Then Try Dim pordersUpdates() As DataRow = Me.PordersItemsDataSet.porders.Select("", "", DataViewRowState.Added Or DataViewRowState.ModifiedCurrent) Dim itemsUpdates() As DataRow = Me.PordersItemsDataSet.items.Select("", "", DataViewRowState.Added Or DataViewRowState.ModifiedCurrent) Dim invoiceUpdates() As DataRow = Me.PordersItemsDataSet.poinvoice.Select("", "", DataViewRowState.Added Or DataViewRowState.ModifiedCurrent) UpdateDatabasePorders() ' Me.PordersTableAdapter.Update(pordersUpdates) UpdateDatabaseItems() ' Me.ItemsTableAdapter.Update(itemsUpdates) UpdateDatabaseInvoice() ' Me.PoinvoiceTableAdapter.Update(invoiceUpdates) Dim pordersDeletes() As DataRow = Me.PordersItemsDataSet.porders.Select("", "", DataViewRowState.Deleted) Dim itemsDeletes() As DataRow = Me.PordersItemsDataSet.items.Select("", "", DataViewRowState.Deleted) Dim invoiceDeletes() As DataRow = Me.PordersItemsDataSet.poinvoice.Select("", "", DataViewRowState.Deleted) Try Me.PoinvoiceTableAdapter.Update(invoiceDeletes) Catch dbcx As System.NullReferenceException MsgBox("This record has already been deleted by another user.") Catch ex As Exception MsgBox("An error was thrown while attempting to update the Invoice Table.") End Try Me.ItemsTableAdapter.Update(itemsDeletes) Me.PordersTableAdapter.Update(pordersDeletes) saved = True Catch ex As Exception MsgBox(ex.ToString) End Try End If Return saved End Function
Anyone have any idea how to handle the concurrency problem when the record is deleted by one user but still visible to another user until they refresh?Code:Private Sub UpdateDatabasePorders() Try Me.PordersTableAdapter.Update(Me.PordersItemsDataSet.porders) 'MsgBox("Update successful on Purchase Orders Table") Catch dbdel As System.NullReferenceException MsgBox("This record was deleted by another user.") Catch dbcx As Data.DBConcurrencyException Dim response As Windows.Forms.DialogResult response = MessageBox.Show(CreateMessagePorders(CType(dbcx.Row, PordersItemsDataSet.pordersRow)), "Concurrency Exception", MessageBoxButtons.YesNo) ProcessDialogResultPorders(response) Catch ex As Exception MsgBox("An error was thrown while attempting to update the Purchase Orders Table.") End Try End Sub Private Function CreateMessagePorders(ByVal crp As PordersItemsDataSet.pordersRow) As String Return "Database: " & GetRowDataPorders(GetCurrentRowInDBPorders(crp), Data.DataRowVersion.Default) & vbCrLf & "Original: " & GetRowDataPorders(crp, Data.DataRowVersion.Original) & vbCrLf & "Proposed: " & GetRowDataPorders(crp, Data.DataRowVersion.Current) & vbCrLf & "Do you still want to update the database with the proposed value?" End Function '-------------------------------------------------------------------------- ' This method loads a temporary table with current records from the database ' and returns the current values from the row that caused the exception. '-------------------------------------------------------------------------- Private TempPordersDataTable As New PordersItemsDataSet.pordersDataTable Private Function GetCurrentRowInDBPorders( ByVal RowWithError As PordersItemsDataSet.pordersRow ) As PordersItemsDataSet.pordersRow Me.PordersTableAdapter.Fill(TempPordersDataTable) Dim currentRowInDbPorders As PordersItemsDataSet.pordersRow = TempPordersDataTable.FindByPONum(RowWithError.PONum) Return currentRowInDbPorders End Function '-------------------------------------------------------------------------- ' This method takes a pordersRow and RowVersion ' and returns a string of column values to display to the user. '-------------------------------------------------------------------------- Private Function GetRowDataPorders(ByVal custRow As PordersItemsDataSet.pordersRow, ByVal RowVersion As Data.DataRowVersion) As String Dim rowData As String = "" For i As Integer = 0 To custRow.ItemArray.Length - 1 rowData &= custRow.Item(i, RowVersion).ToString() & " " Next Return rowData End Function Private Sub ProcessDialogResultPorders(ByVal response As Windows.Forms.DialogResult) Select Case response Case Windows.Forms.DialogResult.Yes PordersItemsDataSet.porders.Merge(TempPordersDataTable, True) UpdateDatabasePorders() Case Windows.Forms.DialogResult.No PordersItemsDataSet.porders.Merge(TempPordersDataTable) MsgBox("Update cancelled for Purchase Orders Table") End Select End Sub
Thanks,
Stacy




Reply With Quote
