Я согласен, что есть несколько "ошибок", и я лично считаю, что SMO-события Microsoft плохо реализованы, поскольку ServerMessageEventArgs содержит свойство Error, которое не всегда предоставляет информацию об ошибке, но сообщения об успешных операциях !!
В качестве примера:
«Ошибка» с кодом 4035 является информационным сообщением. Не ошибка
«Ошибка» с кодом 3014 является информационным сообщением, которое появляется при успешном завершении. Не ошибка
Также обратите внимание, что информационное событие не всегда происходит при возникновении ошибки. Это на самом деле происходит всякий раз, когда SQL Server отправляет сообщение, которое может быть информацией об успешно завершенной операции
Я также обеспокоен не правильной обработкой ошибок / успехов, но проверка sqlError как Null - плохая идея , поскольку он никогда не будет нулевым и всегда будет содержать некоторое сообщение об успешной операции или ошибка. И предположить, что информационное событие происходит при возникновении ошибки, также является плохой идеей .
Я предлагаю обрабатывать ошибки через SqlError.Number и, в зависимости от события SMO, оно было инициировано.
Я сделал следующий код для создания резервной копии базы данных. Это в VB.NET, но в C # будет похоже. Он получает необходимые параметры, включая делегат, где вызывать события (для обработки в графическом интерфейсе), ход выполнения отчета о процентах и обработке ошибок в зависимости от инициируемого события и SqlError.Number, как упомянуто
Public Sub BackupDatabase(databaseName As String, backupFileFullPath As String, optionsBackup As OptionsBackupDatabase, operationProgress As IProgress(Of Integer),
operationResult As Action(Of OperationResult)) Implements IDatabaseManager.BackupDatabase
Dim sqlBackup As New Smo.Backup()
sqlBackup.Action = Smo.BackupActionType.Database
sqlBackup.BackupSetName = databaseName & " Backup"
sqlBackup.BackupSetDescription = "Full Backup of " & databaseName
sqlBackup.Database = databaseName
Dim bkDevice As New Smo.BackupDeviceItem(backupFileFullPath, Smo.DeviceType.File)
sqlBackup.Devices.Add(bkDevice)
sqlBackup.Initialize = optionsBackup.Overwrite
sqlBackup.Initialize = True
sqlBackup.PercentCompleteNotification = 5
AddHandler sqlBackup.PercentComplete, Sub(sender As Object, e As PercentCompleteEventArgs)
operationProgress.Report(e.Percent)
End Sub
AddHandler sqlBackup.Complete, Sub(sender As Object, e As ServerMessageEventArgs)
Dim sqlMessage As SqlClient.SqlError = e.Error
Dim opResult As New OperationResult()
Select Case sqlMessage.Number
Case 3014
opResult.operationResultType = OperationResultType.SmoSuccess
opResult.message = "Backup successfully created at " & backupFileFullPath & ". " & sqlMessage.Number & ": " & sqlMessage.Message
Case Else
opResult.operationResultType = OperationResultType.SmoError
opResult.message = "ERROR CODE " & sqlMessage.Number & ": " & sqlMessage.Message
End Select
operationResult.Invoke(opResult)
End Sub
AddHandler sqlBackup.NextMedia, Sub(sender As Object, e As ServerMessageEventArgs)
Dim sqlMessage As SqlClient.SqlError = e.Error
Dim opResult As New OperationResult()
opResult.operationResultType = OperationResultType.SmoError
opResult.message = "ERROR CODE: " & sqlMessage.Number & ": " & sqlMessage.Message
operationResult.Invoke(opResult)
End Sub
AddHandler sqlBackup.Information, Sub(sender As Object, e As ServerMessageEventArgs)
Dim sqlMessage As SqlClient.SqlError = e.Error
Dim opResult As New OperationResult()
Select Case sqlMessage.Number
Case 4035
opResult.operationResultType = OperationResultType.SmoInformation
opResult.message = sqlMessage.Number & ": " & sqlMessage.Message
Case Else
opResult.operationResultType = OperationResultType.SmoError
opResult.message = "ERROR CODE " & sqlMessage.Number & ": " & sqlMessage.Message
End Select
operationResult.Invoke(opResult)
End Sub
Try
sqlBackup.SqlBackupAsync(smoServer)
Catch ex As Exception
Throw New BackupManagerException("Error backing up database " & databaseName, ex)
End Try
End Sub