Почему не работает простой выбор NHibernate в HQL для базы данных SQLite? - PullRequest
3 голосов
/ 11 августа 2009

Я недавно начал использовать FluenNHibernate, и при попытке написать модульный тест с SQLite появилась странная проблема.

Я использую SQLite в базе данных памяти для тестирования, для каждого метода тестирования я очищаю данные, существующие в базе данных. Например:

var u = new User() { Name = "Piotr" };
_session.Save(u);
_session.Clear();
var list = _session.CreateCriteria<User>().List();

Этот код работает нормально, но когда я пишу в следующей строке:

var list2 = _session.CreateQuery("FROM User").List();

Я получаю:

System.Data.SQLite.SQLiteException: SQLite error
no such table: users

SQL-запрос, сгенерированный NHibernate, в порядке, в чем может быть проблема?

Ответы [ 3 ]

2 голосов
/ 14 августа 2009

Вы упомянули, что используете базу данных SQLite в памяти. Возможно, NHibernate решил закрыть соединение с базой данных между двумя операторами, что может привести к потере всех ваших таблиц.

Один из способов предотвратить это - создать собственную реализацию IConnectionProvider, которая позволяет вам явно контролировать, когда соединение закрыто.

Вот что я использовал для обработки этого в проекте:

public class InMemoryConnectionProvider : IConnectionProvider
{
    private static readonly object syncObject = new object();
    private static SQLiteConnection connection;

    #region IConnectionProvider Members

    public void Configure(IDictionary<string, string> settings)
    {
    }

    public void CloseConnection(IDbConnection conn)
    {
    }

    public IDbConnection GetConnection()
    {
        CreateConnection();
        if (connection.State != ConnectionState.Open)
        {
            connection.Open();
        }
        return connection;
    }

    public IDriver Driver
    {
        get { return new SQLite20Driver(); }
    }

    public void Dispose()
    {
    }

    #endregion

    public static void CreateConnection()
    {
        lock (syncObject)
        {
            if (connection == null)
            {
                var builder = new SQLiteConnectionStringBuilder
                                {
                                    DataSource = ":memory:",
                                    BinaryGUID = true,
                                    DateTimeFormat = SQLiteDateFormats.ISO8601
                                };
                connection = new SQLiteConnection(builder.ConnectionString);
                connection.Open();
            }
        }
    }

    public static void DestroyConnection()
    {
        lock (syncObject)
        {
            if (connection != null)
            {
                connection.Dispose();
                connection = null;
            }
        }
    }
}

Вам также необходимо установить параметр connection.provider в вашем конфигурационном файле, чтобы он указывал на этот класс.

В ваших тестах вы вызываете статический метод InMemoryConnectionProvider.CreateConnection() либо в начале теста, либо в методе настройки. Когда вы закончите, вы позвоните InMemoryConnectionProvider.DestroyConnection(), чтобы закрыть соединение. Поскольку реализация IConnectionProvider.CloseConnection() запрещена, NHibernate не сможет самостоятельно закрыть соединение.

0 голосов
/ 05 октября 2010

У меня были проблемы с SQLite при использовании базы данных в памяти. База данных уничтожается при закрытии соединения / сеанса. Использование варианта файла, кажется, работает лучше.

Кроме того, объекты базы данных должны быть созданы как часть настройки фабрики сеанса. Попробуйте что-то вроде заводской настройки сеанса:

        // Create schema.
        new SchemaExport(config).Create(false, true);
0 голосов
/ 11 августа 2009

Назовите множественное число, может быть? Пользователь - пользователи.

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