3

我想在插入一行时发现违反 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
        }
    }

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

4

1 回答 1

4

这是我工作的非本地化版本,用于捕获唯一键违规,希望对您有所帮助。我抛出了一个调用代码可以捕获和处理的自定义 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;
    }
}
于 2013-09-25T17:55:40.720 回答