NHibernate/Castle activerecord:如何获取导致数据库异常的对象?

NHibernate/Castle activerecord:如何获取导致数据库异常的对象?,nhibernate,castle-activerecord,Nhibernate,Castle Activerecord,我能否以某种方式获取导致GenericADOException(约束异常)的对象 或者我怎样才能只冲洗一个物体,这样我就可以知道哪一个是问题所在 我有一个以表格形式显示的对象列表,可以对其进行编辑和添加。在flush上,它给了我一个数据库异常,但我不能告诉哪个对象出现了异常 我无法将约束移动到nhibernate。您尝试过使用nhibernate探查器吗?它应该会给你更多关于哪个是问题的细节。通过一些谷歌搜索,我找到了一篇有用的帖子,然后通过阅读nhibernate来源,我找到了以下内容:

我能否以某种方式获取导致GenericADOException(约束异常)的对象

或者我怎样才能只冲洗一个物体,这样我就可以知道哪一个是问题所在

我有一个以表格形式显示的对象列表,可以对其进行编辑和添加。在flush上,它给了我一个数据库异常,但我不能告诉哪个对象出现了异常


我无法将约束移动到nhibernate。

您尝试过使用nhibernate探查器吗?它应该会给你更多关于哪个是问题的细节。

通过一些谷歌搜索,我找到了一篇有用的帖子,然后通过阅读nhibernate来源,我找到了以下内容:




我必须对其进行调整,以适应我的稍微过时的nhibernate版本(从3月份开始的2.1版)。我必须对上述内容进行调整,以适应有AdoExceptionContextInfo的较新版本,从中可以获得对象名称和ID。nhibernate很好

我通过肉眼知道是哪一个导致了问题,问题是如何通过代码来确定。我需要知道代码中哪个对象出现了问题,这样我就可以修改或删除它。想一想数据库中的一个独特的约束。虽然我的理解是NHibernate是非常可扩展的,而且很可能您可以从NH获得这些信息,但我怀疑这是否容易。在这一点上,你有两个选择。1.希望像Ayende Rahien这样的专家出现(值得怀疑——更有可能是雇佣他)告诉你如何2。由于您应该将其视为单个工作单元(因此它在事务中),因此对我来说,为每个更新手动调用flush似乎是一个更可能的选项。您知道如何手动刷新一个对象吗?如中所示,告诉会话仅刷新此对象。我有它们的列表,并通过windows窗体上的数据绑定进行更改,所以我无法控制它们在web中的更改时间。
'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