在 Docker 中使用 EF Core 对 SQLite DB 的每个查询都非常慢,除非有对 OpenConnection 的显式调用

Seb*_*ian 6 c# entity-framework docker .net-core

我正在本地主机上运行一个简单的 .NET Core 3.1 Web 应用程序。Web 应用程序在 Docker Linux 容器中运行(我的主机操作系统是 Windows 10)。Web 应用程序使用的 SQLite 数据库使用 EF Core 连接,几乎是空的,非常小,只有 60Kb,每个表有 20 条或更少的记录,并且存储在主机上并使用以下命令为容器挂载:

--mount type=bind,source='SomeDummyHostPath',target=/mnt/hostFolder
Run Code Online (Sandbox Code Playgroud)

问题是在 DBContext 上执行的每个查询都运行得很慢(读取 2 行大约需要 2 秒)。当我在 Docker 容器之外运行应用程序时,一切运行顺利(意味着相同的查询在 ~1ms 内执行)。

奇怪的是,dbContext.Database.OpenConnectionAsync()在每次调用 EF 的 DBSets 之前调用之后,Docker 容器中的每个查询都运行得很快(几毫秒)。

为什么在这种情况下性能如此糟糕?没有OpenConnectionAsync在每次查询之前显式调用的情况下,有什么方法可以改进它?

Luc*_*ian 1

EF Core 3.x 包含一项影响此用例的重大更改,连接会提前关闭:

如果在 TransactionScope 完成之前不再使用数据库连接,则数据库连接将被关闭

缓解措施:

如果连接需要保持打开状态,则显式调用 OpenConnection() 将确保 EF Core 不会过早关闭它

sqlite 提供程序仍未使用连接池13837

随着 EntityFrameworkCore.Sqlite (>3.0) 的新版本,在事务性方面有一些新的优化,并且在打开 .db 文件时会创建新的 .WAL 文件;再加上缺乏连接池,会导致每个请求都创建和删除 .WAL 文件;并且 docker 卷/文件映射到 Windows 文件系统非常耗时。