Nhibernate数据库独立的错误处理

时间:2015-04-14 12:31:57

标签: c# exception nhibernate error-handling

试图找到我最后一个问题的解决方案(https://stackoverflow.com/questions/29539767/sql-nhibernate-exceptions-with-sqlite-and-c-sharp-and-known-error-codes),我决定用我自己的自定义错误包装所有异常。到目前为止我的代码在这里:

    public Exception Convert(NHibernate.Exceptions.AdoExceptionContextInfo exInfo)
    {
        var sqle = (System.Data.SQLite.SQLiteException)exInfo.SqlException;
        var errorDescription = exInfo.SqlException.Message.ToString();
        if (sqle != null)
        {
            //Definition of error codes (for SQLite) to catch and handle
            switch (sqle.ErrorCode)
            {
                //Most possible error in our project: case 19
                case 19:
                    return new ConstraintViolationException(exInfo.Message,
                        sqle.InnerException);
                case 5:
                    return new DbLockedException();
                case 6:
                    return new TableLockedException();
                case 8:
                    return new ReadOnlyDbException();
                case 9:
                    return new InterruptException();
                case 10:
                    return new IOException();
                case 11:
                    return new DbCorruptException();

我从这里开始遵循自定义异常的想法:Returning a custom exception

现在我遇到了一个问题:

因为我们正在使用NHibernate。我们希望保持我们的代码数据库独立。使用您可以看到的代码,它只适用于SQLite。

  • 是否有人知道或了解如何管理错误 无论我使用哪个DB,都能抓住它们?

如果你想保持程序,数据库独立,代码错误不是一个好主意,因为每个数据库都有自己的代码错误和自己的异常。

感谢任何提醒!

2 个答案:

答案 0 :(得分:2)

我在专用程序集中封装了与数据库相关的设置:

  • MyApplication.Data.SqlLite
  • MyApplication.Data.Oracle

每个程序集都包含一组实现公共接口的类,以放入一个公共程序集。在你的情况下,我将创建一个名为DbExceptionConverter的接口和它们的程序集中的implmentation。在应用程序的开始,我将在容器中注册正确的实现。

您也可以将它们全部放在抽象工厂中。

答案 1 :(得分:0)

好的,我最终做的是以下内容:

1-我完整地离开了ORM项目,因为它并不真正需要任何特定的数据库引用或配置(驱动程序等)(程序集将知道hibernate.cfg.xml使用哪个驱动程序)文件)

2- @onof sugested,我创建了一个DbExceptionConverter程序集,其中包含了所有与数据库相关的设置以及我想要使用的每个数据库的例外情况。每个类都用自己的代码包装异常。

我在这里遇到的问题是:"现在,如何加载自定义DbExceptionHandler?" 好吧,我只使用" hibernate.cfg.xml"中的sql_exception_converter属性字段。文件如下:

对于SQLite :(注意sql_exception_converter属性)

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="adonet.batch_size">5000</property>
    <property name="connection.driver_class">NHibernate.Driver.SQLite20Driver</property>
    <property name="connection.connection_string">Data Source=DBFile.db;Version=3;New=True;UseUTF8Encoding=True;</property>
    <property name="sql_exception_converter">DbExceptionConverter.SQLiteExceptionHandler.SqlExceptionConverter, DbExceptionConverter</property>
    <property name="dialect">NHibernate.Dialect.SQLiteDialect</property>
  </session-factory>
</hibernate-configuration>

对于Postgres :(注意sql_exception_converter属性)

<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.provider">NHibernate.Connection.DriverConnectionProvider</property>
    <property name="dialect">NHibernate.Dialect.PostgreSQLDialect</property>
    <property name="connection.driver_class">NHibernate.Driver.NpgsqlDriver</property>
    <property name="connection.connection_string">Server=127.0.0.1;Port=5432;Database=DbName;User Id=postgres;Password=postgres;</property>
    <property name="sql_exception_converter">DbExceptionConverter.PostgresExceptionHandler.SqlExceptionConverter, DbExceptionConverter</property>
  </session-factory>
</hibernate-configuration>

3-在每个sql_exception_converter属性中,您可以看到我使用了类的名称空间和类名来告诉程序集要使用哪个异常处理程序。

事实证明这很容易,我希望我可以用我的经验帮助别人。

如果有人有任何想法,建议,或认为这不是一个好主意,我会很高兴听到它。