1 Attachment(s)
Concurrency Error when record is deleted by another user
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...
Attachment 106691
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...
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
Then the Save() Function that runs this code...
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
These subs are for when it runs the UpdateDatabasePorders. They look basically the same for UpdateDatabaseItems and UpdateDatabaseInvoice.
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
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?
Thanks,
Stacy