Par googling je suis arrivé à un poste qui a été utile, puis en lisant la source NHibernate je suis arrivé à ce qui suit:
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
Je devais l'adapter pour travailler avec ma version nhibernate légèrement obsolète (2.1 de mars) Je vais devoir adapter légèrement ce qui précède pour travailler avec des versions plus récentes où il y a un AdoExceptionContextInfo à partir duquel on peut obtenir le nom et l'ID de l'objet. Nhibernate est bon!
Je sais par œil qui est à l'origine du problème, le problème est de savoir comment le déterminer par code. J'ai besoin de savoir dans le code quel objet donne le problème afin que je puisse le modifier ou le supprimer. Pensez à une contrainte unique dans la base de données. – AngelBlaZe
Bien que je comprenne que NHibernate est assez extensible et il est probable que vous pourriez obtenir cette information de NH Je doute que ce sera facile. À ce stade, vous avez deux options. 1. Espérons qu'un spécialiste comme Ayende Rahien se présente (douteux - plus probable est de l'embaucher) pour vous dire comment 2. Comme vous devriez traiter cela comme une seule unité de travail (d'où il est dans une transaction) appelant vider manuellement pour chaque mise à jour semble être une option plus probable pour moi. –
Savez-vous comment vider manuellement un objet? comme dans dire à une session de vider seulement cet objet. J'ai une liste d'entre eux et d'être changé par liaison de données sur un formulaire Windows, donc je n'ai aucun contrôle de quand ils changent comme on peut dans le web. – AngelBlaZe