.net core EF Core错误:连接不支持MultipleActiveResultSet
我通过所有有错误解决方案的链接进行搜索。但是,它们都不适用于我,因为我已经有了异步代码,并且做了他们建议的一切 我们有基于.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(对象对象对象)中.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.
在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操作,Func4验证成功,TState状态,CancellationToken CancellationToken)位于Microsoft.EntityFrameworkCore.Query.Internal.QueryingEnumerable
1.AsyncEnumerator.MoveNextAsync()
在Microsoft.EntityFrameworkCore.EntityFrameworkQueryableExtensions.ToListSync[TSource](IQueryable1 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