迭代上下文类型 'Volo.Saas.EntityFrameworkCore.SaasDbContext 的查询结果时发生异常

An exception occurred while iterating over the results of a query for context type 'Volo.Saas.EntityFrameworkCore.SaasDbContext

异常消息和堆栈跟踪:

2021-11-03 21:21:43.774 -05:00 [ERR] 迭代上下文类型 'Volo.Saas.EntityFrameworkCore.SaasDbContext' 的查询结果时发生异常。 System.Threading.Tasks.TaskCanceledException: 任务已取消。 在 Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.InitializeAsync(DbDataReader reader,IReadOnlyList1 columns, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.InitializeAsync(IReadOnlyList1 列,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.InitializeAsync(IReadOnlyList1 columns, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.InitializeReaderAsync(DbContext _,布尔结果,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState 状态, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.MoveNextAsync() System.Threading.Tasks.TaskCanceledException: A task was canceled. at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.InitializeAsync(DbDataReader reader, IReadOnlyList1 列,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.InitializeAsync(IReadOnlyList1 columns, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.InitializeAsync(IReadOnlyList1 列,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.InitializeReaderAsync(DbContext _, Boolean result, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func4 操作中,Func4 verifySucceeded, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.MoveNextAsync() 2021-11-03 21:21:43.838 -05:00 [ERR] 任务已取消。 System.Threading.Tasks.TaskCanceledException: 任务已取消。 在 Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.BufferedDataRecord.InitializeAsync(DbDataReader reader,IReadOnlyList1 columns, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.InitializeAsync(IReadOnlyList1 列,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Query.Internal.BufferedDataReader.InitializeAsync(IReadOnlyList1 columns, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject, CancellationToken cancellationToken) at Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.InitializeReaderAsync(DbContext _,布尔结果,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.SqlServer.Storage.Internal.SqlServerExecutionStrategy.ExecuteAsync[TState,TResult](TState 状态, Func4 operation, Func4 verifySucceeded, CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Query.Internal.SplitQueryingEnumerable1.AsyncEnumerator.MoveNextAsync() at Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable1 asyncEnumerable,CancellationToken cancellationToken) 在 Microsoft.EntityFrameworkCore.Query.ShapedQueryCompilingExpressionVisitor.SingleOrDefaultAsync[TSource](IAsyncEnumerable1 asyncEnumerable, CancellationToken cancellationToken) at Volo.Abp.Domain.Repositories.EntityFrameworkCore.EfCoreRepository3.FindAsync(TKey id, Boolean includeDetails, CancellationToken cancellationToken) 在 Castle.DynamicProxy.AsyncInterceptorBase.ProceedAsynchronous[TResult](IInvocation 调用,IInvocationProceedInfo proceedInfo) 在 Volo.Abp.Castle.DynamicProxy.CastleAbpMethodInvocationAdapterWithReturnValue1.ProceedAsync() at Volo.Abp.Uow.UnitOfWorkInterceptor.InterceptAsync(IAbpMethodInvocation invocation) at Volo.Abp.Castle.DynamicProxy.CastleAsyncAbpInterceptorAdapter1.InterceptAsync[TResult](IInvocation 调用,IInvocationProceedInfo proceedInfo,Func3 proceed) at Volo.Saas.Tenants.TenantStore.GetCacheItemAsync(Nullable1 id,字符串名称) 在 Volo.Saas.Tenants.TenantStore.FindAsync(引导 ID) 在 ClientsLink.Data.ClientsLinkTenantDatabaseMigrationHandler.MigrateAndSeedForTenantAsync(Guid tenantId, String adminEmail, String adminPassword) 在 D:\Century\Internal\Clients.Link\Clients.Link\src\ClientsLink.Domain\Data\ClientsLinkTenantDatabaseMigrationHandler.cs:line 98

这发生在下面突出显示的代码行中:

private async Task MigrateAndSeedForTenantAsync(
    Guid tenantId,
    string adminEmail,
    string adminPassword)
{
  try
  {
    using (_currentTenant.Change(tenantId))
    {
      // Create database tables if needed
      using (var uow = _unitOfWorkManager.Begin(requiresNew: true, isTransactional: false))
      {
        var tenantConfiguration = await _tenantStore.FindAsync(tenantId); // EXCEPTION THROWN HERE
        if (tenantConfiguration?.ConnectionStrings != null &&
            !tenantConfiguration.ConnectionStrings.Default.IsNullOrWhiteSpace())
        {
          foreach (var migrator in _dbSchemaMigrators)
          {
            _logger.LogDebug($"Running migration {migrator.ToString()}");
            await migrator.MigrateAsync();
          }
        }

        await uow.CompleteAsync();
      }

重现问题的步骤

  1. 使用 ABP Commercial Suite v 4.4.3 生成示例分层 MVC 应用程序
  2. 添加几个实体 - 一个全局实体和一个带导航的多租户 属性 到全局实体
  3. 创建示例数据库
  4. 运行 DbMigrator - 主机数据库将成功迁移
  5. 运行 Web 应用程序,以管理员身份登录,创建一个新的测试租户 - 大约一分钟后,UI 报告内部错误并记录上述异常

经过两周的工作,这似乎很明显,有些东西阻止了 _tenantStore.FindAsync(tenantId) 调用的执行。

哪些可能的事情会导致该调用超时或被取消?

请考虑您的回复并尽可能详细。

我已经更换了所有组件。我在两台独立的机器上构建和重建。我已经重写了我的数据种子贡献者。我已将 System.Data.SqlClient 换成 Microsoft.Data.SqlClient 并将命令超时连接字符串参数设置为 2 3600。两周内我没有尝试解决这个问题。

终于在这个post找到了答案:https://support.abp.io/QA/Questions/2084/An-exception-occurred-while-iterating-over-the-results-of-a-query-for-context-type-%27VoloSaasEntityFrameworkCoreSaasDbContexspendinng

正如您从屏幕截图中看到的那样,解决方案是将 requiresNew 参数设置为 false。这是必要的,因为调用方法上的 [UnitOfWork] 属性已经启动了一个正在处理的事务。