我正在使用Nancy为数据库创建api,并希望针对内存数据库进行测试/开发。
我在一个带有连接字符串Data Source=:memory:
的自定义引导程序类中使用我的数据库类的实例,而后者又创建了必要的表 - 我已经逐步完成了这一点,我确信这已经发生了。
然后我使用相同的连接字符串来获取新连接以加载/保存数据,但即使是简单的选择也会出现表不存在的sql错误。
创建和使用具有相同连接字符串的新连接的逻辑是否存在错误?
答案 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
,可以解决多个连接问题。
但是,这不是问题的解决方案,因为一旦最后一个连接关闭,数据库就不再存在。