Basically, the SQL operation behind the linkbutton is taking some time to complete and users will click this button more than once before the SQL operation completes. It is a DELETE Operation and does an implicit ReBind. But before the ReBind occurs to remove the row from the grid the user may have clicked it serveral times already....causing an error.
The desired behavior would be to not allow the RadGrid.DeleteCommandName to fire if this operation was already in progress.
Private
Sub RadGrid1_ItemDataBound(ByVal sender As Object, ByVal e As Telerik.Web.UI.GridItemEventArgs) Handles RadGrid1.ItemDataBound
If
TypeOf e.Item Is GridDataItem Then
Dim dataItem As GridDataItem = CType(e.Item, GridDataItem)
' create custom delete prompt
Dim classnametext As String = dataItem("NAME").Text
Dim button As LinkButton = CType(dataItem("column").Controls(0), LinkButton)
button.Attributes(
"onclick") = "return confirm('Are you sure you want to delete class: " & classnametext & " ?')"
End If
End Sub
Private Sub RadGrid1_ItemCommand(ByVal source As Object, ByVal e As Telerik.Web.UI.GridCommandEventArgs) Handles RadGrid1.ItemCommand
' supress columns in Edit-Mode for the following STATUS' OPEN-CLOSED
If ddlClassStatus.SelectedValue = "Open" Or ddlClassStatus.SelectedValue = "Closed" Then
Dim firstColumn As GridEditCommandColumn = CType(e.Item.OwnerTableView.GetColumnSafe("EditCommandColumn"), GridEditCommandColumn)
If (e.CommandName = RadGrid.EditCommandName) Then
' create custom EditRecord link
Dim dataItem As GridDataItem = CType(e.Item, GridDataItem)
Dim linkButton As LinkButton = New LinkButton
' supress columns in Edit-Mode for the following STATUS' OPEN-CLOSED
If ddlClassStatus.SelectedValue = "Open" Or ddlClassStatus.SelectedValue = "Closed" Then
dataItem(
"EditCommandColumn").Text = "<br>"
End If
End If
End If
' delete class and all associated data
If (e.CommandName = RadGrid.DeleteCommandName) Then
' determine class status
Dim _classid As String = e.Item.OwnerTableView.DataKeyValues(e.Item.ItemIndex)("CLASSID").ToString()
Dim connectionString As String = ConfigurationManager.ConnectionStrings("HRregistrationConnectionString").ToString
Dim SqlConnection As New SqlConnection(connectionString)
Dim SqlCommand As New SqlCommand
Dim SqlStatement As New StringBuilder
Dim SqlLookupStatement1 As String
Dim SqlLookupStatement2 As String
Dim SqlLookupStatement3 As String
Dim SqlLookupStatement4 As String
Dim SqlLookupStatement5 As String
Dim SqlLookupStatement6 As String
Dim SqlLookupStatement7 As String
Dim SqlLookupStatement8 As String
Dim SqlLookupStatement9 As String
Dim RecordsAffected As Integer
'Open the SqlConnection
SqlConnection.Open()
' put this in a transaction
Using txn As SqlTransaction = SqlConnection.BeginTransaction
Try
' lookup the CLASSSTATUS.STATUSTYPEID
Dim _statustypeid As String
SqlLookupStatement1 =
"SELECT STATUSTYPEID FROM DBO.CLASSSTATUS WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement1
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_statustypeid = System.Convert.ToString(SqlCommand.ExecuteScalar)
' lookup the CLASSES.NAME
Dim _name As String
SqlLookupStatement2 =
"SELECT NAME FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement2
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_name = System.Convert.ToString(SqlCommand.ExecuteScalar)
' lookup the STATUSTYPE.STATUSCODE
Dim _statuscode As String
SqlLookupStatement3 =
"SELECT STATUSCODE FROM DBO.STATUSTYPE WHERE STATUSTYPEID = '" + _statustypeid + "'"
SqlCommand.CommandText = SqlLookupStatement3
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_statuscode = System.Convert.ToString(SqlCommand.ExecuteScalar)
If _statuscode = "Open" Then ' class [Open] being deleted -- notify enrolled users and Admins of cancellation
'lookup the CLASSES.DATE
Dim _date As String
SqlLookupStatement7 =
"SELECT DATE FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement7
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_date = System.Convert.ToString(SqlCommand.ExecuteScalar)
'lookup the CLASSES.STARTIME
Dim _starttime As String
SqlLookupStatement4 =
"SELECT STARTTIME FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement4
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_starttime = System.Convert.ToString(SqlCommand.ExecuteScalar)
'lookup the CLASSES.ENDTIME
Dim _endtime As String
SqlLookupStatement5 =
"SELECT ENDTIME FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement5
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_endtime = System.Convert.ToString(SqlCommand.ExecuteScalar)
'lookup the CLASSES.LOCATION
Dim _location As String
SqlLookupStatement6 =
"SELECT LOCATION FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement6
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_location = System.Convert.ToString(SqlCommand.ExecuteScalar)
'lookup the CLASSES.DESCRIPTION
Dim _description As String
SqlLookupStatement8 =
"SELECT DESCRIPTION FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement8
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_description = System.Convert.ToString(SqlCommand.ExecuteScalar)
' user list
SqlLookupStatement3 =
"SELECT REGISTEREDUSER.NAME, REGISTEREDUSER.EMAILADDRESS FROM DBO.REGISTEREDUSER INNER JOIN REGISTRATIONSTATUS ON REGISTEREDUSER.REGISTEREDUSERID = REGISTRATIONSTATUS.REGISTEREDUSERID INNER JOIN STATUSTYPE ON REGISTRATIONSTATUS.STATUSTYPEID = STATUSTYPE.STATUSTYPEID WHERE (REGISTRATIONSTATUS.CLASSID ='" + _classid + "' AND STATUSTYPE.STATUSCODE ='Enrolled')"
SqlCommand.CommandText = SqlLookupStatement3
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
' prepare data adapters/rows
Dim da_email_user As New SqlDataAdapter(SqlCommand)
Dim ds_email_user As New DataSet
Dim row_email_user As DataRow
Dim _emailaddress As String
Dim _username As String
Dim _userlist As New StringBuilder
da_email_user.Fill(ds_email_user)
For Each row_email_user In ds_email_user.Tables(0).Rows
_emailaddress = row_email_user(
"EMAILADDRESS")
_username = row_email_user(
"NAME")
' send Cancellation e-mail
SendCancellationEmail(_emailaddress, _name, _username, _date, _starttime, _endtime, _location, _description)
' create affected user list
_userlist.AppendLine(_username)
Next
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
' wait list
SqlLookupStatement9 =
"SELECT REGISTEREDUSER.NAME, REGISTEREDUSER.EMAILADDRESS FROM DBO.REGISTEREDUSER INNER JOIN REGISTRATIONSTATUS ON REGISTEREDUSER.REGISTEREDUSERID = REGISTRATIONSTATUS.REGISTEREDUSERID INNER JOIN STATUSTYPE ON REGISTRATIONSTATUS.STATUSTYPEID = STATUSTYPE.STATUSTYPEID WHERE (REGISTRATIONSTATUS.CLASSID ='" + _classid + "' AND STATUSTYPE.STATUSCODE ='Waiting')"
SqlCommand.CommandText = SqlLookupStatement9
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
' prepare data adapters/rows
Dim da_wait_user As New SqlDataAdapter(SqlCommand)
Dim ds_wait_user As New DataSet
Dim row_wait_user As DataRow
Dim _waitusername As String
Dim _waituserlist As New StringBuilder
da_wait_user.Fill(ds_wait_user)
For Each row_wait_user In ds_wait_user.Tables(0).Rows
_waitusername = row_wait_user(
"NAME")
' create wait list
_waituserlist.AppendLine(_waitusername)
Next
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.APPLICATIONLINKS WHERE CLASSID = '" + _classid + "'")
Dim deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.REMINDERS WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.DISCLAIMER WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.REGISTRATIONSTATUS WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.CLASSSTATUS WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' determine if the user has no other classes associated; then delete their profile
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.REGISTEREDUSER WHERE REGISTEREDUSERID NOT IN(SELECT REGISTEREDUSERID FROM DBO.REGISTRATIONSTATUS WHERE REGISTEREDUSERID = REGISTEREDUSER.REGISTEREDUSERID)")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' commit transaction
txn.Commit()
SqlLookupStatement1 =
"SELECT AD_EMAILADDRESS FROM DBO.APPUSER"
SqlCommand.CommandText = SqlLookupStatement1
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
' prepare data adapters/rows
Dim da_email_admin As New SqlDataAdapter(SqlCommand)
Dim ds_email_admin As New DataSet
Dim row_email_admin As DataRow
da_email_admin.Fill(ds_email_admin)
For Each row_email_admin In ds_email_admin.Tables(0).Rows
_emailaddress = row_email_admin(
"AD_EMAILADDRESS")
' send Administrative e-mail
SendAdminEmail(_emailaddress, _userlist, _waituserlist, _name, _date, _starttime, _endtime, _location, _description, _statuscode)
Next
Else ' class [Pending/Closed] being deleted -- no notifications needed
'lookup the CLASSES.DATE
Dim _date As String
SqlLookupStatement7 =
"SELECT DATE FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement7
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_date = System.Convert.ToString(SqlCommand.ExecuteScalar)
'lookup the CLASSES.STARTIME
Dim _starttime As String
SqlLookupStatement4 =
"SELECT STARTTIME FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement4
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_starttime = System.Convert.ToString(SqlCommand.ExecuteScalar)
'lookup the CLASSES.ENDTIME
Dim _endtime As String
SqlLookupStatement5 =
"SELECT ENDTIME FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement5
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_endtime = System.Convert.ToString(SqlCommand.ExecuteScalar)
'lookup the CLASSES.LOCATION
Dim _location As String
SqlLookupStatement6 =
"SELECT LOCATION FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement6
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_location = System.Convert.ToString(SqlCommand.ExecuteScalar)
'lookup the CLASSES.DESCRIPTION
Dim _description As String
SqlLookupStatement8 =
"SELECT DESCRIPTION FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'"
SqlCommand.CommandText = SqlLookupStatement8
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
_description = System.Convert.ToString(SqlCommand.ExecuteScalar)
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
' user list
SqlLookupStatement3 =
"SELECT REGISTEREDUSER.NAME, REGISTEREDUSER.EMAILADDRESS FROM DBO.REGISTEREDUSER INNER JOIN REGISTRATIONSTATUS ON REGISTEREDUSER.REGISTEREDUSERID = REGISTRATIONSTATUS.REGISTEREDUSERID INNER JOIN STATUSTYPE ON REGISTRATIONSTATUS.STATUSTYPEID = STATUSTYPE.STATUSTYPEID WHERE (REGISTRATIONSTATUS.CLASSID ='" + _classid + "' AND STATUSTYPE.STATUSCODE ='Enrolled')"
SqlCommand.CommandText = SqlLookupStatement3
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
' prepare data adapters/rows
Dim da_email_user As New SqlDataAdapter(SqlCommand)
Dim ds_email_user As New DataSet
Dim row_email_user As DataRow
Dim _emailaddress As String
Dim _username As String
Dim _userlist As New StringBuilder
da_email_user.Fill(ds_email_user)
For Each row_email_user In ds_email_user.Tables(0).Rows
_username = row_email_user(
"NAME")
' create affected user list
_userlist.AppendLine(_username)
Next
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
' wait list
SqlLookupStatement9 =
"SELECT REGISTEREDUSER.NAME, REGISTEREDUSER.EMAILADDRESS FROM DBO.REGISTEREDUSER INNER JOIN REGISTRATIONSTATUS ON REGISTEREDUSER.REGISTEREDUSERID = REGISTRATIONSTATUS.REGISTEREDUSERID INNER JOIN STATUSTYPE ON REGISTRATIONSTATUS.STATUSTYPEID = STATUSTYPE.STATUSTYPEID WHERE (REGISTRATIONSTATUS.CLASSID ='" + _classid + "' AND STATUSTYPE.STATUSCODE ='Waiting')"
SqlCommand.CommandText = SqlLookupStatement9
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
' prepare data adapters/rows
Dim da_wait_user As New SqlDataAdapter(SqlCommand)
Dim ds_wait_user As New DataSet
Dim row_wait_user As DataRow
Dim _waitusername As String
Dim _waituserlist As New StringBuilder
da_wait_user.Fill(ds_wait_user)
For Each row_wait_user In ds_wait_user.Tables(0).Rows
_waitusername = row_wait_user(
"NAME")
' create wait list
_waituserlist.AppendLine(_waitusername)
Next
SqlLookupStatement1 =
"SELECT AD_EMAILADDRESS FROM DBO.APPUSER"
SqlCommand.CommandText = SqlLookupStatement1
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
' prepare data adapters/rows
Dim da_email_admin As New SqlDataAdapter(SqlCommand)
Dim ds_email_admin As New DataSet
Dim row_email_admin As DataRow
da_email_admin.Fill(ds_email_admin)
For Each row_email_admin In ds_email_admin.Tables(0).Rows
_emailaddress = row_email_admin(
"AD_EMAILADDRESS")
' send Administrative e-mail
SendAdminEmail(_emailaddress, _userlist, _waituserlist, _name, _date, _starttime, _endtime, _location, _description, _statuscode)
Next
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.APPLICATIONLINKS WHERE CLASSID = '" + _classid + "'")
Dim deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.REMINDERS WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.DISCLAIMER WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.REGISTRATIONSTATUS WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.CLASSSTATUS WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.CLASSES WHERE CLASSID = '" + _classid + "'")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' determine if the user has no other classes associated; then delete their profile
' reset sql statement
SqlStatement.Remove(0, SqlStatement.Length)
RecordsAffected = 0
SqlStatement.Append(
"DELETE FROM DBO.REGISTEREDUSER WHERE REGISTEREDUSERID NOT IN(SELECT REGISTEREDUSERID FROM DBO.REGISTRATIONSTATUS WHERE REGISTEREDUSERID = REGISTEREDUSER.REGISTEREDUSERID)")
deleteQuery = SqlStatement.ToString
SqlCommand.CommandText = deleteQuery
SqlCommand.Connection = SqlConnection
SqlCommand.Transaction = txn
RecordsAffected = SqlCommand.ExecuteNonQuery()
' commit transaction
txn.Commit()
End If
Catch ex As Exception
' rollback transaction
txn.Rollback()
RadGrid1.Controls.Add(
New LiteralControl("Unable to Delete. Reason: " + ex.Message))
e.Canceled =
True
End Try
End Using
' end transaction
' close the SqlConnection
SqlConnection.Close()
End If
End Sub