内存中的SQLite和数据库正在消失

时间:2017-05-10 05:26:18

标签: c# sqlite

我正在使用Nancy为数据库创建api,并希望针对内存数据库进行测试/开发。

我在一个带有连接字符串Data Source=:memory:的自定义引导程序类中使用我的数据库类的实例,而后者又创建了必要的表 - 我已经逐步完成了这一点,我确信这已经发生了。

然后我使用相同的连接字符串来获取新连接以加载/保存数据,但即使是简单的选择也会出现表不存在的sql错误。

创建和使用具有相同连接字符串的新连接的逻辑是否存在错误?

2 个答案:

答案 0 :(得分:2)

您需要保持SQLiteConnection处于打开状态,并确保DbContext 拥有该连接。这样,当容器放置DbContext时,连接不会被它关闭。注意:这仅适用于EF6。您仍然可以在EF5中传递该标志,但是当上下文被释放时,上下文仍将关闭连接。

我创建了一个TestBootstrapper,它从Web项目继承了工作的Bootstrapper。

作为ConfigureRequestContainer方法的一部分,我在DbContext注册上使用了一个方法工厂,每次创建一个新的DbContext,但使用现有连接。如果您不这样做,DbContext将在您第一次请求后被处理,第二个请求将失败。

public class TestBootstrapper : Bootstrapper
{
    private const string ConnectionString = "data source=:memory:;cache=shared;";
    private static SQLiteConnection _connection;
    private static TestInitializer _initializer = new TestInitializer();

    protected override void ConfigureRequestContainer(TinyIoCContainer, NancyContext context) 
    {
        container.Register<Context>((_,__) => 
        {
            if (_connection == null)
                _connection = new SQLiteConnection(ConnectionString);

            // The false flag tells the context it does not own the connection, i.e. it cannot close it. (EF6 behaviour only)
            var dbContext = new Context(_connection, _initializer, false);

            if (_connection.State == ConnectionState.Closed)
                _connection.Open();

            // I build the DB and seed it here
            _initializer.InitializeDatabase(context);

            return dbContext;
        });

        // Additional type registrations
    }

    // Call this method on a [TearDown]
    public static void Cleanup() 
    {
        if (_connection != null && _connection.State == ConnectionState.Open)
            _connection.Close();
        _connection = null;
    }
}

答案 1 :(得分:1)

好的,直接来自文档:

  

数据库连接关闭后,数据库就不再存在。 &#34;

但是,通过在连接字符串中使用cache=shared,可以解决多个连接问题。

但是,这不是问题的解决方案,因为一旦最后一个连接关闭,数据库就不再存在。