Если вы определяете уникальное ограничение в базе данных, то почему бы не делегировать ответственность за проверку того, существует ли уникальное значение в базе данных? Используя NHibernate, вы можете использовать интерфейс NHibernate.Exceptions.ISQLExceptionConverter
для захвата и преобразования известных ошибок, связанных с нарушениями ограничений. Вы также можете использовать NHibernate.Exceptions.IViolatedConstraintNameExtracter
реализации (см. NHibernate.Exceptions.TemplatedViolatedConstraintNameExtracter
), чтобы получить подробные сведения об исключении из вашей базы данных, преобразовать его в удобное для пользователя сообщение, упаковать в качестве исключения проверки вашего выбора и перехватить его в соответствующем контроллере. ,
Пример быстрого, очень специфического быстрого и грязного конвертера исключений из одного из моих проектов:
Imports NHibernate
Imports NHibernate.Exceptions
Imports System.Data.SqlClient
Imports System.Data.Common
Namespace NHibernate
Public Class ConstraintViolationExceptionConverter
Implements ISQLExceptionConverter
Public Function Convert(ByVal adoExceptionContextInfo As Global.NHibernate.Exceptions.AdoExceptionContextInfo) As System.Exception Implements Global.NHibernate.Exceptions.ISQLExceptionConverter.Convert
Dim dbEx As DbException = ADOExceptionHelper.ExtractDbException(adoExceptionContextInfo.SqlException)
If TypeOf dbEx Is SqlException Then
Dim sqlError As SqlException = DirectCast(dbEx, SqlException)
Select Case sqlError.Number
Case 547
Return New ConstraintViolationException(adoExceptionContextInfo.Message, adoExceptionContextInfo.SqlException)
End Select
End If
Return SQLStateConverter.HandledNonSpecificException(adoExceptionContextInfo.SqlException, adoExceptionContextInfo.Message, adoExceptionContextInfo.Sql)
End Function
End Class
End Namespace
Настраивается через элемент свойства web.config/nhibernate-configuration/session-factory
:
<property name="sql_exception_converter">csl.NHibernate.ConstraintViolationExceptionConverter, csl</property>
Редактировать: Вероятно, следует упомянуть, что интерфейс конвертера изменился в последних версиях NHibernate, интерфейс из этого примера взят из NHibernate.dll v2.1.0.4000