Reputation: 4665
I am using Nancy to create an api to a database, and am wanting to test / develop against an in-memory database.
I am using an instance of my database class in a custom bootstrapper class with the connection string Data Source=:memory:
, which in turn is creating the necessary tables - I have stepped through this and I'm confident this is occuring.
I am then obtaining a new connection using the same connection string to load/save data, but even a simple select is coming up with the sql error that the table doesn't exist.
Is there a fault in this logic of creating and using a new connection with the same connection string?
Upvotes: 1
Views: 2163
Reputation: 2611
You need to keep the SQLiteConnection
open and ensure that the DbContext
does not own the connection. This way, when the DbContext
is disposed by the container, the connection doesn't get closed with it. Note: This only works with EF6. You can still pass the flag in EF5, but the context will still close the connection when the context gets disposed.
I created a TestBootstrapper
which inherited the working Bootstrapper from the web project.
As part of the ConfigureRequestContainer
method, I used a method factory on the DbContext
registration which created a new DbContext
each time, but used the existing connection. If you don't do this, the DbContext
will get disposed after your first request and the second request will fail.
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;
}
}
Upvotes: 2
Reputation: 4665
OK, so straight from the docs:
The database ceases to exist as soon as the database connection is closed. "
However, this can be worked around with multiple connections by using cache=shared
in your connection string.
However, this isn't a solution to the problem because as soon as the last connection closes, the database ceases to exist.
Upvotes: 2