I have code like:
private async void GetCommonInfo(HttpResponse res, MyDbContext db)
{
long lastUpdated = await db.InfoUpdated.Select(r => r.Common).FirstOrDefaultAsync();
var info = new CommonInfo
{
ARows = await QueryTool.AllIndexByID(db.TableA),
BRows = await QueryTool.AllIndexByID(db.TableB),
CRows = await QueryTool.AllIndexByID(db.TableC),
LastUpdated = lastUpdated,
};
await res.WriteAsJsonAsync(info);
}
while:
public class QueryTool
{
public static async Task<Dictionary<int, T>> AllIndexByID<T>(DbSet<T> dbSet)
where T : class, ITableModel
{
return (await dbSet.AsNoTracking().ToListAsync()).ToDictionary(b => b.ID, b => b);
}
}
When I call this method I get this exception:
fail: Microsoft.EntityFrameworkCore.Query[10100]
An exception occurred while iterating over the results of a query for context type 'ApiServer.Models.MyDbContext'.
System.ObjectDisposedException: Cannot access a disposed context instance. A common cause of this error is disposing a context instance that was resolved from dependency injection and then later trying to use the same context instance elsewhere in your application. This may occur if you are calling 'Dispose' on the context instance, or wrapping it in a using statement. If you are using dependency injection, you should let the dependency injection container take care of disposing context instances.
Object name: 'MyDbContext'.
at Microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
at Microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
at Microsoft.EntityFrameworkCore.DbContext.Microsoft.EntityFrameworkCore.Internal.IDbContextDependencies.get_StateManager()
at Microsoft.EntityFrameworkCore.Query.QueryContextDependencies.get_StateManager()
at Microsoft.EntityFrameworkCore.Query.QueryContext.InitializeStateManager(Boolean standAlone)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.InitializeReaderAsync(AsyncEnumerator enumerator, CancellationToken cancellationToken)
at Pomelo.EntityFrameworkCore.MySql.Storage.Internal.MySqlExecutionStrategy.ExecuteAsync[TState,TResult](TState state, Func`4 operation, Func`4 verifySucceeded, CancellationToken cancellationToken)
at Microsoft.EntityFrameworkCore.Query.Internal.SingleQueryingEnumerable`1.AsyncEnumerator.MoveNextAsync()
It looks like that a dependency injected DbContext
can only be used for one query, then it is disposed.
How do I solve this by like, using sync methods or integrate four queries into one query if I am able to, do not use dependency injection, or something else?
CodePudding user response:
Your problem is async void
.
Replace with async Task
and don't forget to await GetCommonInfo
.
Additional info: async/await - when to return a Task vs void?