EntityFrameworkCore SQLite in-memory db tables are not created EntityFrameworkCore SQLite in-memory db tables are not created sqlite sqlite

EntityFrameworkCore SQLite in-memory db tables are not created


Using a non-shared SQLite in-memory database

SQLite in-memory databases are by default transient. As the documentation states:

The database ceases to exist as soon as the database connection is closed. Every :memory: database is distinct from every other.

EF Core's DbContext on the other hand, always opens and closes connections to the database automatically, unless you pass an already open connection.

Therefore, in order to use the same SQLite in-memory database across multiple calls in EF Core, you need to create a SqliteConnection object separately and then pass it to every DbContext.

For example:

  var keepAliveConnection = new SqliteConnection("DataSource=:memory:");  keepAliveConnection.Open();  services.AddDbContext<MyContext>(options =>  {    options.UseSqlite(keepAliveConnection);  });

Note that SqliteConnection isn't really thread-safe, so this approach is applicable only to single-threaded scenarios. Any time you want to have a shared database that can be accessed by multiple threads (e.g. in an ASP.NET Core application, servicing multiple requests), you should consider using an on-disk database.

By the way, this is the approach currently used in the EF Core documentation on how to use SQLite in-memory databases for testing.

Using a shared SQLite in-memory database

SQLite also supports named shared in-memory databases. By using the same connection string, multiple SqliteConnection objects can connect to the same database. However:

The database is automatically deleted and memory is reclaimed when the last connection to the database closes.

So it is still necessary to maintain a separate open connection object for the database to be usable across multiple EF Core calls. For example:

  var connectionString = "DataSource=myshareddb;mode=memory;cache=shared";  var keepAliveConnection = new SqliteConnection(connectionString);  keepAliveConnection.Open();  services.AddDbContext<MyContext>(options =>  {    options.UseSqlite(connectionString);  });

Note that this approach isn’t limited to a single thread, because each DbContext gets its own instance of SqliteConnection.