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

标签 c# nhibernate exception fluent-nhibernate

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

  1. 关系型数据库 - MSSQL Server 2008
  2. 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
        }
    }

如果有人有 Eagle-Eye,请分享 :) 谢谢!

最佳答案

这是我用于捕获唯一 key 违规的非本地化版本,希望对您有所帮助。我抛出一个调用代码可以捕获和处理的自定义 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;
    }
}

关于c# - 流利的 NHibernate,实现 ISQLExceptionConverter 的正确方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19010082/

相关文章:

c# - nhibernate 审计更新事件

java - DynamoDBMapper - 无法实例化类

c# - 对继承类的最小起订量测试总是返回 null

NHibernate 组件映射 VS IUserType

c# - NHibernate <一对多>

java - eclipse 调试器 - 在特定位置引发异常时的断点

结合 lambda 和 multi-catch 子句时出现 Java 错误?

c# - Binary(16) 字段正在截断 Guid 的尾随零

c# - 有没有办法查明是否已设置属性或变量?

c# - 如何使用 CLI 函数在 C# 中使用数组参数?