我们有一个已经成功运行了5年的ASP.Net Core 3.1 Rest API。它使用EF Core 5.1与SQLite数据库进行交互。
我们现在正在将数据库从SQLite迁移到AWS Aurora Postgres。
考虑到这一点,我们已经添加了Npgsql.EntityFrameworkCore.PostgresSQL nuget包,并修改了连接字符串,类似于以下内容:
我们有一套针对API运行的集成测试。当连接到SQLite数据库时,所有测试都能成功运行。 然而,当运行针对Postgres的测试时,在运行了大约20个测试后开始出现以下错误:
"The connection pool has been exhausted, either raise MaxPoolSize (currently 100) or Timeout (currently 15 seconds)"
我尝试通过添加"Pooling=false"来更改连接字符串,结果仍然出现相同的错误。 然后我尝试移除"Pooling=false"并添加"Maximum Pool Size = 200"(以及更多)。同样,结果还是出现了相同的错误。
因为这些更改没有任何影响,我怀疑EF并没有使用我认为的连接字符串,所以我故意将连接字符串中的Database元素更改为一个不存在的数据库名称,结果立即失败。从而证明确实使用了正确的连接字符串。
关于我们使用EF Core的其他注意事项:
我们不是注入一个具体的DbContext类,而是将一个IContext接口注入到我们的服务中。
我们像这样在服务集合中注册接口:
Context类的样子如下:
就像我说的,这个代码库多年来一直在与SQLite成功地配合使用。但是当然,与Npgsql一样,SQLite没有连接池的概念。
我已经阅读了Postgres Npgsql Connection Pooling和其他相关的SO帖子,但是无法找出问题所在。
你有什么想法我们做错了什么吗?
我们现在正在将数据库从SQLite迁移到AWS Aurora Postgres。
考虑到这一点,我们已经添加了Npgsql.EntityFrameworkCore.PostgresSQL nuget包,并修改了连接字符串,类似于以下内容:
"Host=[Our AWS host]; Port=5432; User ID=postgres; Password=XXXXXXXX; Database=api_test_db"
我们有一套针对API运行的集成测试。当连接到SQLite数据库时,所有测试都能成功运行。 然而,当运行针对Postgres的测试时,在运行了大约20个测试后开始出现以下错误:
"The connection pool has been exhausted, either raise MaxPoolSize (currently 100) or Timeout (currently 15 seconds)"
我尝试通过添加"Pooling=false"来更改连接字符串,结果仍然出现相同的错误。 然后我尝试移除"Pooling=false"并添加"Maximum Pool Size = 200"(以及更多)。同样,结果还是出现了相同的错误。
因为这些更改没有任何影响,我怀疑EF并没有使用我认为的连接字符串,所以我故意将连接字符串中的Database元素更改为一个不存在的数据库名称,结果立即失败。从而证明确实使用了正确的连接字符串。
关于我们使用EF Core的其他注意事项:
我们不是注入一个具体的DbContext类,而是将一个IContext接口注入到我们的服务中。
我们像这样在服务集合中注册接口:
services.AddScoped<IContext>(serviceProvider =>
{
var connectionString = "...";
var context = new Context(connectionString);
return context;
});
Context类的样子如下:
public class Context : DbContext, IContext
{
...
protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
if (_connectionString.ToLower().Contains("sqlite"))
{
optionsBuilder.UseSqlite(_connectionString,
options => options.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery));
}
else
{
optionsBuilder.UseNpgsql(_connectionString,
options => options.UseQuerySplittingBehavior(QuerySplittingBehavior.SingleQuery))
}
}
}
就像我说的,这个代码库多年来一直在与SQLite成功地配合使用。但是当然,与Npgsql一样,SQLite没有连接池的概念。
我已经阅读了Postgres Npgsql Connection Pooling和其他相关的SO帖子,但是无法找出问题所在。
你有什么想法我们做错了什么吗?
AddDbContext
?什么是IContext
?你发布的内容并不是使用EF的标准方式,所以很难猜测发生了什么。我怀疑代码使用的是singleton而不是作用域实例,或者至少在没有正确关闭它们的情况下创建新的DbContext实例。 - undefined