Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Entity Framework Core connection management

In an asp.net core project, I need an encrypted SQLite database. For that, I made my own SqliteEncryptedConnection which inherits from Microsoft.Data.Sqlite.SqliteConnection and which sets the encryption key in the Open() method (execute PRAGMA key = ...)

I have an extension method that configures my EF context by creating a connection and giving it.

    public static void UseEncryptedSqlite(this DbContextOptionsBuilder optionsBuilder, string connectionString, string password)
    {
        var connection = new SqliteEncryptedConnection(connectionString, password);
        connection.Open();
        optionsBuilder.UseSqlite(connection);
    }

I must open the connection before I give it to EF, otherwise it is automatically opened and closed by EF for each single query, and the Open() method is now quite expensive.

My problem with this solution is that my connection is never disposed nor closed!

  1. Is it correct to set the encryption key in Open?
  2. Is there a way to know when the context is disposed? Or to configure it to close and dispose the connection after it is disposed?
  3. Is there another (better) way to manage the connection?

The dirty solution would be to dispose the connection in the EF context's Dispose method, but I don't really want to dispose a dependency that was injected and not owned by the context.

like image 491
sroll Avatar asked Oct 12 '17 16:10

sroll


1 Answers

I had an answer from Brice Lambson who works in the EF core team:

You're going in the right direction--open connections less. Remember, SQLite connections are essentially just file streams, so keeping them open longer isn't really an issue.

If there's only ever one DbContext instance per connection, the DbContext can still own the connection even if it's created externally. Just dispose the connection inside of DbContext.Dispose().

If that's not enough, you could try creating a connection pool. Managing the lifetime might get tricky. The important thing is that a connection doesn't get used outside of the thread it was created on.

Using Cache=Shared (i.e. Shared-Cache Mode) might also help throughput.

like image 140
sroll Avatar answered Oct 14 '22 13:10

sroll