我有一个以典型方式设置的EF Core网站。效果很好。
但是,我添加了一个Controller Method,它每秒被命中几次,并且当有多个活动线程时,EF会引发异常。如果请求相隔几秒钟,那么它可以正常工作。
我已经尝试调试此功能,但是我看不到我在做什么错。
以下是详细信息:
这些请求来自单个页面应用程序,它们都是相同的连接。如果只有一个请求,则可以正常工作。但是,如果有两个请求,则会引发异常。
System.IndexOutOfRangeException HResult = 0x80131508 Message = Index在数组范围之外。 源= System.Data 堆栈跟踪: 在System.Data.SqlClient.SqlDataReader.CheckHeaderIsReady(Int32 columnIndex,布尔allowAsync,字符串methodName) 在System.Data.SqlClient.SqlDataReader.IsDBNull(Int32 i) 在Microsoft.EntityFrameworkCore.Storage.Internal.TypedRelationalValueBufferFactory.Create(DbDataReader dataReader) 在Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable
1.AsyncEnumerator.<BufferlessMoveNext>d__12.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.<ExecuteImplementationAsync>d__31
2.MoveNext() 在Microsoft.EntityFrameworkCore.Storage.ExecutionStrategy.d__312.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable
1.AsyncEnumerator.d__11.MoveNext() 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor1.EnumeratorExceptionInterceptor.<MoveNext>d__5.MoveNext() at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at System.Linq.AsyncEnumerable.<Aggregate_>d__6
3.MoveNext() 在System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在System.Runtime.CompilerServices.TaskAwaiter`1.GetResult() 在Traken.Data.Repositories.LookupListItemRepository.d__4.MoveNext()中的C:\ Dev \ Traken.app \ Traken.5 \ Dev \ Traken \ Data \ Repositories \ LookupListItemRepository.cs:第38行
正在使用的存储库:
services.AddScoped<LookupListItemRepository, LookupListItemRepository>();
我也尝试过AddTransient
,但遇到相同的错误。
services.AddTransient<LookupListItemRepository, LookupListItemRepository>();
DbContext:
services.AddDbContext<ApplicationDbContext>(optionsBuilder =>
{
optionsBuilder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
options => options.EnableRetryOnFailure());
});
控制器
[HttpGet("{tableName}")]
public async Task<List<LookupListItem>> GetLookupTableAsync(string tableName) => await this._repository.List(tableName);
存储库
public async Task<List<LookupListItem>> List(string tableName)
{
return await this._dbContext.LookupTables.FromSql(
$@"{SqlStrings.SP.GetLookupTable}
@tableName = {tableName}"
).AsNoTracking().ToListAsync();
}
我该如何解决?
答案 0 :(得分:0)
我通过将存储库设置为AddTransient
而不是AddScoped
来解决此问题
services.AddTransient<LookupListItemRepository, LookupListItemRepository>();
,并将上下文的生存期设置为Transient
。
services.AddDbContext<ApplicationDbContext>(optionsBuilder =>
{ optionsBuilder.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"),
options => options.EnableRetryOnFailure());
}, ServiceLifetime.Transient);
另请参阅:https://docs.microsoft.com/en-us/ef/core/querying/async
public async Task<List<Blog>> GetBlogsAsync()
{
using (var context = new BloggingContext())
{
return await context.Blogs.ToListAsync();
}
}