【发布时间】:2018-03-24 16:12:09
【问题描述】:
在一个 asp.net 核心项目中,我需要一个加密的 SQLite 数据库。为此,我创建了自己的SqliteEncryptedConnection,它继承自Microsoft.Data.Sqlite.SqliteConnection,并在Open() 方法中设置了加密密钥(执行PRAGMA key = ...)
我有一个扩展方法,它通过创建连接并提供它来配置我的 EF 上下文。
public static void UseEncryptedSqlite(this DbContextOptionsBuilder optionsBuilder, string connectionString, string password)
{
var connection = new SqliteEncryptedConnection(connectionString, password);
connection.Open();
optionsBuilder.UseSqlite(connection);
}
我必须先打开连接,然后再交给EF,否则每次查询都会被EF自动打开和关闭,Open()方法现在相当昂贵。
我对这个解决方案的问题是我的连接从未被释放或关闭!
- 在Open中设置加密密钥是否正确?
- 有没有办法知道上下文何时被释放?还是将其配置为在释放连接后关闭并释放连接?
- 还有其他(更好的)方法来管理连接吗?
肮脏的解决方案是在 EF 上下文的 Dispose 方法中释放连接,但我真的不想释放注入但不属于上下文的依赖项。
【问题讨论】:
-
如果我正确理解您的问题,它就是设计使然。
DbContextOptions对象不会被释放,并且将被 EF Core DbContext 的所有实例重用,因为选项在初始化时传递给 DbContext。从 2.0 preview1 开始,甚至可以轮询 DbContext 实例以获取高性能场景,请参阅blog post -
@Tseng 连接没有被重用。每次注入新的 DbContext 时都会调用此方法。 -> 每个网络请求 1 个。幸运的是,这些连接似乎被正确地垃圾收集了。所以,最后,我不知道如果在垃圾收集发生之前没有调用 dispose/close 是否有问题。
-
您找到解决方案了吗?如果 EF Core 上下文接收到已打开的连接,我也有同样的问题。在我的情况下,我无法在选项对象中关闭它,因为我需要在分片环境中建立连接,这就是我从
ShardMap对象的OpenConnectionForKey方法接收它的方式。 -
@AdrianPavel 我用 Brice Lambson 的回复回答了我的问题。在您的情况下,如果连接由单个上下文使用,则可以安全地将其放置在上下文
Dispose方法中
标签: .net sqlite asp.net-core entity-framework-core