2009-07-16 6 views
1

Kann ich irgendwie das Objekt bekommen, das eine GenericADOException verursacht hat (constraint exception)?NHibernate/Castle activerecord: Wie bekomme ich ein Objekt, das eine Datenbankausnahme verursacht hat?

Oder Wie kann ich nur ein Objekt spülen, damit ich sagen kann, welches das Problem ist.

Ich habe eine Liste von Objekten, die in einem Formular angezeigt werden und bearbeitet und hinzugefügt werden können. Auf Flush gibt es mir eine Datenbank-Ausnahme, aber ich kann nicht sagen, welches Objekt die Ausnahme gab.

Ich kann die Einschränkung nicht zu Nhibernate verschieben.

Antwort

0

Durch einige googeln ich auf einen Posten bekam, die hilfreich war, dann durch die nhibernate Quelle zu lesen bekam ich auf die folgenden:

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 

Ich musste es anpassen, um damit zu arbeiten meine etwas veraltete Nhibernate-Version (2.1 ab März) Ich werde das obige leicht anpassen müssen, um mit neueren Versionen zu arbeiten, wo es eine AdoExceptionContextInfo gibt, von der man den Objektnamen und die ID bekommen kann. Nhibernate ist gut!

0

Haben Sie versucht, NHibernate Profiler zu verwenden? Es sollte Ihnen zusätzliche Details darüber geben, welches das Problem ist.

+0

Ich weiß durch den Augapfel, welches das Problem verursacht, das Problem ist, wie man das durch den Code bestimmt. Ich muss im Code wissen, welches Objekt das Problem gibt, also kann ich es entweder ändern oder löschen. Denken Sie an eine eindeutige Einschränkung in der Datenbank. – AngelBlaZe

+0

Während mein Verständnis ist, dass NHibernate ist sehr erweiterbar und es ist wahrscheinlich, dass Sie diese Informationen von NH erhalten konnte, bezweifle ich, dass es einfach sein wird. An diesem Punkt haben Sie zwei Möglichkeiten. 1. Hoffe, dass ein Spezialist wie Ayende Rahien auftaucht (zweifelhaft - wahrscheinlicher ist ihn einzustellen), um Ihnen zu sagen, wie 2. Da sollten Sie dies als eine Einheit der Arbeit behandeln (daher ist es in einer Transaktion) aufrufen Flush manuell für jedes Update scheint eine wahrscheinliche Option für mich. –

+0

Wissen Sie, wie Sie ein Objekt manuell spülen können? wie in einer Sitzung zu sagen, nur um dieses Objekt zu spülen. Ich habe eine Liste von ihnen und wird durch Datenbindung auf einem Windows-Formular geändert, so habe ich keine Kontrolle darüber, wenn sie sich ändern, wie man im Web kann. – AngelBlaZe

Verwandte Themen