.net core EF Core错误:连接不支持MultipleActiveResultSet

.net core EF Core错误:连接不支持MultipleActiveResultSet,.net-core,entity-framework-core,azure-functions,ef-core-3.1,.net Core,Entity Framework Core,Azure Functions,Ef Core 3.1,我通过所有有错误解决方案的链接进行搜索。但是,它们都不适用于我,因为我已经有了异步代码,并且做了他们建议的一切 我们有基于.NETCore3.1的Azure功能。我们使用最新版本的实体框架核心。我们间歇性地出现以下错误: System.InvalidOperationException:该连接不支持多个活动结果集 在System.Threading.Tasks.ContinuationResultTaskFromResultTask2.InnerInvoke()中的Microsoft.Data.

我通过所有有错误解决方案的链接进行搜索。但是,它们都不适用于我,因为我已经有了异步代码,并且做了他们建议的一切

我们有基于.NETCore3.1的Azure功能。我们使用最新版本的实体框架核心。我们间歇性地出现以下错误:

System.InvalidOperationException:该连接不支持多个活动结果集

在System.Threading.Tasks.ContinuationResultTaskFromResultTask2.InnerInvoke()中的Microsoft.Data.SqlClient.SqlCommand.c.b_u164_0(任务<代码>1结果) 在System.Threading.Tasks.Task.c.b_u274_0(对象对象对象)中
在System.Threading.ExecutionContext.RunInternal(ExecutionContext ExecutionContext,ContextCallback回调,对象状态)
来自引发异常的上一个位置的堆栈结束跟踪

在System.Threading.ExecutionContext.RunInternal(ExecutionContext ExecutionContext,ContextCallback回调,对象状态)
在System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task¤tTaskSlot,threadPoolThread)
来自引发异常的上一个位置的堆栈结束跟踪---

位于Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject,CancellationToken CancellationToken)
位于Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject,CancellationToken CancellationToken)
位于Microsoft.EntityFrameworkCore.Storage.RelationalCommand.ExecuteReaderAsync(RelationalCommandParameterObject parameterObject,CancellationToken CancellationToken) 在Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable
1.AsyncEnumerator.InitializeReaderAsync(DbContext),布尔结果,CancellationToken CancellationToken)的Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](在Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.ExecuteImplementationAsync[TState,TResult](Func
4操作,Func
4验证成功,TState状态,CancellationToken CancellationToken)位于Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable
1.AsyncEnumerator.MoveNextAsync() 在Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListSync[TSource](IQueryable
1 source,CancellationToken CancellationToken)在Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListSync[TSource](IQueryable
1 source,CancellationToken CancellationToken)

当我们查看AppInsights中的日志时,发现异常同时发生,同一位置的同一函数出现完全相同的错误。但是,这是针对三个不同的调用(InvocationId),但相同的主机实例(HostInstanceId)和不同的操作Id(操作Id).Expectation是,对于每个新调用,新的dbContext将被实例化为默认情况下AddDbContextPool将作用域dbContext添加为依赖项。不确定是否可以从中扣除任何内容

以下是我们的实施方法。感谢您的帮助。提前感谢

我们在启动文件中使用以下语句向服务添加
DbContext

builder.Services.AddDbContextPool<OurDbContext>(options =>
{
    options.UseSqlServer("connectionstring"), builder =>
    {
       builder.EnableRetryOnFailure(3, TimeSpan.FromSeconds(2), null);
    });
});
然后我们将
OurDbContext
类注入到不同的存储库中,这些存储库使用此上下文与SQL对话。如下所示:

public class TypesRepo : RepoBase<Types>, ITypesRepo
{
  public TypesRepo(OurDbContext ourDbContext) : base(ourDbContext)
  {
  }
  
  public async Task RetrieveTypesAsync(List<string> types)
  {
    var records = await RetrieveConditionAsync(x => types.Contains(x.Type));
    return records?.Select(x => new { x.Type, x.TypeId })
                   .ToDictionary(x => x.Type, x => x.TypeId);
  }
}

public abstract class RepoBase<T> where T : class
{
    protected OurDbContext OurDbContext  { get; set; }

    public RepoBase(OurDbContext OurDbContext)
    {
        this.OurDbContext = OurDbContext;
    }

    public async Task<List<T>> RetrieveConditionAsync(Expression<Func<T, bool>> expression)
    {
        return await OurDbContext.Set<T>().Where(expression).AsNoTracking().ToListAsync();
    }
}
备注:基于以下评论
我认为dbcontextpool将重用dbcontext实例,如果它连接不是活动/未使用的,但不是活动的


您的连接字符串需要指定
MultipleActiveRecordSets=true;
以告诉SqlServer确保在与它的连接上启用此功能

例如:

Data Source=localhost;Initial Catalog=master;Integrated Security=True;MultipleActiveResultSets=True

此处的详细信息:

您的连接字符串需要指定
MultipleActiveRecordSets=true;
以告诉SqlServer确保在与它的连接上启用此功能

例如:

Data Source=localhost;Initial Catalog=master;Integrated Security=True;MultipleActiveResultSets=True

这里有更多信息:

我们最近遇到了一个类似的问题,这是由于一个请求同时启动多个线程,而每个线程都使用相同的
DbContext
来并行化繁重的数据库查询

此外,我们使用
DbReader
处理结果,这将锁定连接,直到处理完读取器

这可以防止其他线程重新使用相同的DbContext/connection实例,这些线程也使用
DbReader
来处理结果


启用多个活动结果集功能为我们解决了这一问题,在我们的例子中,我们实际上根本没有注意到性能受到影响。

我们最近遇到了类似的问题,原因是请求同时启动多个线程,每个线程都使用相同的
DbContext
来并行化heavy数据库查询

此外,我们使用
DbReader
处理结果,这将锁定连接,直到处理完读取器

这可以防止其他线程重新使用相同的DbContext/connection实例,这些线程也使用
DbReader
来处理结果


启用多个活动结果集功能为我们解决了这一问题,在我们的例子中,我们实际上根本没有注意到性能受到影响。

是的,我在多个地方读到了这一点,但同时它说,如果启用MARS,性能会受到影响。在这种情况下,由于这是三个不同的dbcontext实例,每个实例一个查询只有一个结果集。不确定它为什么会抛出此错误。我也不确定在这种情况下为什么需要启用MARS?这是实体框架的最大好处之一:透明性
Data Source=localhost;Initial Catalog=master;Integrated Security=True;MultipleActiveResultSets=True