数据库
首页 > 数据库> > c#-流利的NHibernate,实现ISQLExceptionConverter的正确方法

c#-流利的NHibernate,实现ISQLExceptionConverter的正确方法

作者:互联网

我想在插入一行时捕获违反UNIQUE KEY约束的情况,但不知道如何.

> RDBMS-MSSQL Server 2008
> NHibernate 3.3版本

NHibernate配置:

public NHibernate.Cfg.Configuration GetConfiguration()
    {
        string connectionString = System.Configuration.ConfigurationManager.ConnectionStrings["ConnectionSqlServer"].ConnectionString;
        var cfg = Fluently.Configure()
                          .Database(MsSqlConfiguration.MsSql2008
                          .ConnectionString(connectionString)
                          .ShowSql()
                          .Driver<NHibernate.Driver.Sql2008ClientDriver>()
                          .Provider<NHibernate.Connection.DriverConnectionProvider>()
                          .Dialect<NHibernate.Dialect.MsSql2008Dialect>())
                          .Mappings(m => m.FluentMappings.AddFromAssemblyOf<EntityBase>().Conventions.Add(DynamicUpdate.AlwaysTrue()))
                          .ExposeConfiguration(config =>
                              {
                                  config.SetInterceptor(new SqlStatementInterceptor());
                                  config.SetProperty(Environment.SqlExceptionConverter,
                                      typeof(MsSqlExceptionConverter).AssemblyQualifiedName);
                                  config.Properties[Environment.CurrentSessionContextClass] = "web";
                                  var schemaUpdate = new SchemaUpdate(config);
                                      schemaUpdate.Execute(false, true);
                              })
                          .BuildConfiguration();
        return cfg;
    }

ISQLExceptionConverter实现:

public class MsSqlExceptionConverter : ISQLExceptionConverter
{
    public Exception Convert(AdoExceptionContextInfo exInfo)
    {
        var sqle = ADOExceptionHelper.ExtractDbException(exInfo.SqlException) as SqlException;
        if (sqle != null)
        {
            switch (sqle.Number)
            {
                case 547:
                    return new ConstraintViolationException(exInfo.Message,
                        sqle.InnerException, exInfo.Sql, null);
                case 208:
                    return new SQLGrammarException(exInfo.Message,
                        sqle.InnerException, exInfo.Sql);
                case 3960:
                    return new StaleObjectStateException(exInfo.EntityName, exInfo.EntityId);
            }
        }
        return SQLStateConverter.HandledNonSpecificException(exInfo.SqlException,
            exInfo.Message, exInfo.Sql);
    }
}

try-catch语句:

public void InsertCultures()
    {
        using (var uow = _unitOfWorkFactory.Create())
        {
            var CULTURE_DEFAULTS = new List<Culture>()
            {
                new Culture() {Symbol = "ro-RO", Language = "Romana"},
                new Culture() {Symbol = "ru-RU", Language = "Rusa"},
                new Culture() {Symbol = "en-US", Language = "Engleza"}
            };

            foreach (var culture in CULTURE_DEFAULTS)
            {
                try
                {
                    _cultureRepository.Create(culture);
                }
                catch (ConstraintViolationException e)
                {

                }

            }
           /// Other stuff
        }
    }

如果有人有鹰眼,请分享:)谢谢!

解决方法:

这是我正在工作的非本地化版本,用于捕获唯一的键冲突,希望对您有所帮助.我抛出了一个自定义的UniqueKeyException,调用代码可以捕获和处理该异常.您的Fluent配置代码对我来说似乎正确.

public class SqlServerExceptionConverter : ISQLExceptionConverter
{
    public Exception Convert(AdoExceptionContextInfo adoExceptionContextInfo)
    {
        var sqlException = adoExceptionContextInfo.SqlException as SqlException;
        if (sqlException != null)
        {
            // 2601 is unique key, 2627 is unique index; same thing: 
            // http://blog.sqlauthority.com/2007/04/26/sql-server-difference-between-unique-index-vs-unique-constraint/
            if (sqlException.Number == 2601 || sqlException.Number == 2627)
            {
                return new UniqueKeyException(sqlException.Message, sqlException);
            }
        }
        return adoExceptionContextInfo.SqlException;
    }
}

标签:exception-handling,nhibernate,c,fluent-nhibernate
来源: https://codeday.me/bug/20191030/1967436.html