简体   繁体   English

实体框架核心连接管理

[英]Entity Framework Core connection management

In an asp.net core project, I need an encrypted SQLite database. 在asp.net核心项目中,我需要一个加密的SQLite数据库。 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 = ...) 为此,我创建了自己的SqliteEncryptedConnection ,它继承自Microsoft.Data.Sqlite.SqliteConnection并在Open()方法中设置加密密钥(执行PRAGMA key = ...)

I have an extension method that configures my EF context by creating a connection and giving it. 我有一个扩展方法,通过创建连接并给它来配置我的EF上下文。

    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. 我必须在将它提供给EF之前打开连接,否则EF会为每个单独的查询自动打开和关闭它,而Open()方法现在非常昂贵。

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? 在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. 脏解决方案是在EF上下文的Dispose方法中处理连接,但我真的不想处置注入的依赖项,而不是由上下文拥有的依赖项。

I had an answer from Brice Lambson who works in the EF core team: 我得到了在EF核心团队工作的Brice Lambson的答案:

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. 请记住,SQLite连接本质上只是文件流,因此保持打开时间不是真正的问题。

If there's only ever one DbContext instance per connection, the DbContext can still own the connection even if it's created externally. 如果每个连接只有一个DbContext实例,DbContext仍然可以拥有连接,即使它是在外部创建的。 Just dispose the connection inside of DbContext.Dispose(). 只需将连接部署在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 (ie Shared-Cache Mode ) might also help throughput. 使用Cache = Shared(即共享缓存模式 )也可能有助于吞吐量。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM