NHibernate с C # -Sqlite не имеет DbConnection в> .NET 2.0 - PullRequest
0 голосов
/ 12 августа 2010

Я попытался запустить свои модульные тесты с C # Sqlite вместо того, чтобы переходить на реальную базу данных или чертовски издеваться над уровнем нашей базы данных, используя этот пост в качестве руководства: Nhibernate C # Sqlite .

К сожалению, NHibernate требует, чтобы соединение было DbConnection, которое не предоставляется драйвером C # -Sqlite.Я заглянул в исходный код и заметил следующий код:

#if NET_2_0
public class SqliteConnection : DbConnection, ICloneable
#else
    public class SqliteConnection : IDbConnection, ICloneable
#endif

По-видимому, автор решил прекратить "старые" базовые классы и использовать вместо них интерфейсы IDbConnection, IDbTransaction, ....

Изменение кода не вариант, потому что это было бы равносильно написанию нового клиента, который должен быть протестирован и поддержан.

Кто-нибудь знает простое решение для получения текущей версии c # sqlite для работы с NHibernate?

Ответы [ 3 ]

1 голос
/ 12 августа 2010

Я тестирую с использованием sqlite. У меня другой подход.

Я позволил NH создать соединение, но сохранил его в статической переменной, чтобы передать его в последующие сеансы.

Когда я начал писать тестовый фреймворк, у меня был такой код инициализации:

static IDbConnection staticSqliteConnection;

if (staticSqlliteConnection == null)
{
  sessionFactory.CreateSession().Connection;
}

Тогда у меня были некоторые проблемы, и у меня было слишком много тестового кода в моем рабочем коде (я предпочитаю не иметь его). Генераторы идентификаторов Hi-Lo также не работают, если вы передаете соединение сеансу.

Затем я написал класс ConnectionProvider, похожий на этот:

public class SingleConnectionProvider : DriverConnectionProvider
{
    private static IDbConnection staticConnection = null;

    public static void ResetConnection()
    {
        if (staticConnection == null) return;
        staticConnection.Dispose();
        staticConnection = null;
    }

    public override IDbConnection GetConnection()
    {
        if (staticConnection == null) 
        {
            staticConnection = base.GetConnection();
        }
        if (staticConnection.State != ConnectionState.Open)
        {
            staticConnection.Open();
        }
        return staticConnection;
    }

    protected override void Dispose(bool isDisposing)
    {
        ResetConnection();
    }
}

В методе очистки модульного теста вы вызываете SingleConnectionProvider.ResetConnection(), который уничтожает базу данных для следующего теста.

Все это, конечно, не является полностью безопасным для потоков. Вы можете создать столько сеансов, сколько захотите, но вам следует избегать их одновременного создания.

0 голосов
/ 24 августа 2010

Я решил проблему, используя System.Data.SQLite и пользовательский поставщик подключений:

public class SqLiteInMemoryConnectionProvider : DriverConnectionProvider
{
    public static IDbConnection Connection;

    public static event EventHandler ConnectionReset;

    public static void ResetConnection()
    {
        if(Connection == null) return;

        Connection.Close();
        Connection.Open();

        if(ConnectionReset != null) ConnectionReset(null, new EventArgs());
    }

    public override IDbConnection GetConnection()
    {
        if (Connection == null)
        {
            Connection = base.GetConnection();
        }
        if (Connection.State != ConnectionState.Open)
        {
            Connection.Open();
        }
        return Connection;
    }

    public override void CloseConnection(IDbConnection conn) { }
}

Отличия от решения Stefan Steineggers заключаются в том, что я закрываю и снова открываю сеанс для сброса, потому что NHibernate не может получить новое соединение, если я только что удалил его. Далее я добавил событие для использования в своем классе фабрики для перестройки фабрики сеанса (которая экспортирует нашу схему в базу данных)

SqLiteInMemoryConnectionProvider.ConnectionReset += (s, _) => RebuildSessionFactory();
0 голосов
/ 13 августа 2010

Если вы посмотрите на пример кода,

#if NET_2_0
public class SqliteConnection : DbConnection, ICloneable
#else
    public class SqliteConnection : IDbConnection, ICloneable
#endif

Вы можете увидеть, что, определив опцию компилятора NET_2_0 и перекомпилировав, он откроет старые интерфейсы

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...