NHibernate / Castle activerecord: как получить объект, вызвавший исключение базы данных? - PullRequest
1 голос
/ 16 июля 2009

Могу ли я как-нибудь получить объект, вызвавший GenericADOException (исключение ограничения)?

Или Как я могу очистить только один объект, чтобы определить, в чём проблема.

У меня есть список объектов, которые отображаются в форме, и которые можно редактировать и добавлять в. При сбросе это дает мне исключение базы данных, но я не могу сказать, какой объект дал исключение.

Я не могу переместить ограничение в nhibernate.

Ответы [ 2 ]

0 голосов
/ 17 июля 2009

Путем некоторого поиска в Google я получил сообщение, которое было полезно, затем, прочитав исходный код nhibernate, я получил следующее:

http://fabiomaulo.blogspot.com/2009/06/improving-ado-exception-management-in.html


'http://fabiomaulo.blogspot.com/2009/06/improving-ado-exception-management-in.html
'properties.Add("sql_exception_converter", "SmartCore.SmartDatabaseExceptionConverter, SmartCore")
Class SmartDatabaseExceptionConverter
    Implements ISQLExceptionConverter


    Public Function Convert(ByVal sqlException As System.Exception, ByVal message As String, ByVal sql As NHibernate.SqlCommand.SqlString) As NHibernate.ADOException Implements NHibernate.Exceptions.ISQLExceptionConverter.Convert

        Dim sqle As DbException
        sqle = ADOExceptionHelper.ExtractDbException(sqlException)
        '"could not update: [SmartCore.GL.Glaccount#1225]"
        Dim obname As String
        Dim key As String
        obname = ExtractUsingTemplate("could not update: [", "#", message)
        key = ExtractUsingTemplate("#", "]", message)

        Dim prikey As Integer
        prikey = Integer.Parse(key)

        sqle.Data.Add("obname", obname)
        sqle.Data.Add("prikey", key)

        If sqle.ErrorCode = 335544558 Then
            '"Operation violates CHECK constraint C_GLACCOUNT on view or table GLACCOUNT At trigger 'CHECK_56'"
            Dim checkname As String
            checkname = ExtractUsingTemplate("Operation violates CHECK constraint ", "on view or table ", sqle.Message)
            Return New SmartDatabaseConstraintException(message, sqle, obname, prikey, checkname)
            'Return New ConstraintViolationException(message, sqle, sql, checkname)
        End If

        Return SQLStateConverter.HandledNonSpecificException(sqlException, message, sql)
    End Function



    Protected Function ExtractUsingTemplate(ByVal templateStart As String, ByVal templateEnd As String, ByVal message As String) As String
        Dim templateStartPosition As Integer = message.IndexOf(templateStart)
        If templateStartPosition < 0 Then
            Return Nothing
        End If

        Dim start As Integer = templateStartPosition + templateStart.Length
        Dim [end] As Integer = message.IndexOf(templateEnd, start)
        If [end] < 0 Then
            [end] = message.Length
        End If

        Return message.Substring(start, [end] - start).Trim()

    End Function
End Class

'USAGE
        Try
            _scope.Flush()
        Catch ex As SmartDatabaseConstraintException
            If ex.ConstraintName = "C_GLACCOUNT" Then
                Dim gla As GL.Glaccount
                gla = GL.Glaccount.Find(ex.EntityId) 'should be fast from entity cache
                msgboxError(gla.description & " is duplicate please rename")
            Else
                msgboxError(ex.Message)
            End If
        End Try

Мне пришлось адаптировать его для работы с моей слегка устаревшей версией nhibernate (2.1 с марта). Мне придется немного адаптировать вышеописанное для работы с новыми версиями, где есть AdoExceptionContextInfo, из которого можно получить имя объекта и идентификатор. Nhibernate это хорошо!

0 голосов
/ 16 июля 2009

Вы пробовали использовать NHibernate Profiler? Он должен дать вам дополнительную информацию о том, какая из них является проблемой.

...