2015-04-14 2 views
1

, пытаясь найти решение для моей последней проблемы (https://stackoverflow.com/questions/29539767/sql-nhibernate-exceptions-with-sqlite-and-c-sharp-and-known-error-codes), я решил обернуть все исключения своими собственными ошибками. Вот мой код до сих пор:Независимая обработка данных базы данных Nhibernate

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

Я инкапсулированные настройки базы данных в зависимости от выделенных в сборках:

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

Каждый узел содержит набор классов, реализующий общий интерфейс поставить общую сборку. В вашем случае я бы сделал интерфейс с именем DbExceptionConverter и импликацией в своих сборках. В начале приложения я бы зарегистрировал в контейнере правильную реализацию.

Вы также можете разместить их на абстрактной фабрике.

+0

Спасибо за ответ! Это звучит очень хорошо, подход, который я принимал, был немного сложным. Я думаю, что это будет лучший способ. Я думал о чем-то подобном ловлю общих исключений, а затем сделал перевод, но я не думаю, что это так просто, как кажется. –

0

Хорошо, что я в конце концов сделал следующий:

1- я оставил проект ORM нетронутыми, как это на самом деле не нуждается в какой-либо конкретной ссылки DB или конфигурации (драйверы, ... и т.д.) (сборка будет знать, какой драйвер использовать файл hibernate.cfg.xml)

2- как @onof sugested, я создал сборку DbExceptionConverter, где у меня были все параметры, зависящие от базы данных, и исключения для каждой БД, которую я хотел использовать. Каждый класс обертывает исключения своими собственными кодами.

Вопрос, который у меня был здесь: «Теперь, как загрузить пользовательский DbExceptionHandler?» Ну, я просто использую поле свойства sql_exception_converter в поле "hibernate.cfg.файл XML»следующим образом:

Для 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, вы можете видеть, что я использовал пространство имен класса и имя класса, чтобы сообщить сборке, какой обработчик исключений использовать.

Это оказалось очень легко, и я надеюсь, что смогу помочь кому-то еще с моим опытом в этом.

Если у кого-то есть идеи, предложения или мысли, что это не такая хорошая идея, я буду рад это услышать.

Смежные вопросы