EF Core 连接池似乎无法与用户分配的托管标识一起正常工作。我的网页从我的 Angular 前端到 Web API 控制器进行了 3 次 Ajax 调用。控制器使用包含实现 DbContext
的 IDisposable
的存储库类。
我们使用默认依赖容器和默认 DbContext
设置运行带有 EF Core 的 .NET Core 3.1,所以它是 ServiceLifeTime.Scoped
。
我的 DbContext
ctor 有这样的代码用于托管身份。
var connection = (Microsoft.Data.SqlClient.SqlConnection)Database.GetDbConnection();
var options = new DefaultAzureCredentialOptions { ManagedIdentityClientId = surveyToolOptions.Value.ManagedIdentityClientId };
var credential = new DefaultAzureCredential(options);
var token = credential.GetToken(new Azure.Core.TokenRequestContext(new[] { "https://database.windows.net/.default" }));
connection.AccessToken = token.Token;
当我查看会话计数时,每次点击页面时它都会增加 3 个连接。它永远不会重用连接。他们也不会离开大约 4-5 分钟。
SELECT host_name, Program_name, COUNT(*)
FROM sys.dm_exec_sessions s
JOIN sys.databases AS d ON s.database_id = d.database_id
GROUP BY host_name, Program_name
这是一个问题,因为 Azure SQL 数据库的会话数量非常有限。 https://docs.microsoft.com/en-us/azure/azure-sql/database/resource-limits-dtu-single-databases#standard-service-tier
当我使用用户 ID 和密码将其切换到标准 SQL Server 身份验证时,它按预期工作。
使用托管身份时是否需要关闭连接池?这似乎确实有效,但我确信在关闭池的情况下建立连接需要更长的时间。
-兰迪
答案 0 :(得分:0)
如果您在每个请求上都创建一个新的 DBContext
,并且它在构造函数中调用 credential.GetToken(...)
,那么您很可能每次都以不同的令牌结束,因此无法将连接池化。< /p>
在构造函数之外检索和存储令牌应该可以解决这个问题。