I use these statements:
using (var factory = _contextFactory.CreateDbContext())
{
var itemsQueryable = factory.Set<AppUser>().AsQueryable();
var result = itemsQueryable?.Where(c => c.AccessFailedCount <= maxMedals);
...
}
this is a factory of my identityContext, but when I run the code, there is an error:
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.
what is this error and how to make it work?
@inject IDbContextFactory<IdentityContext> _contextFactory
@codes {
IQueryable<AppUser> FilteredCountries
{
get
{
using (var factory = _contextFactory.CreateDbContext())
{
var itemsQueryable = factory.Set<AppUser>().AsQueryable();
var result = itemsQueryable?.Where(c => c.AccessFailedCount <= maxMedals);
if (!string.IsNullOrEmpty(nameFilter))
{
result = result.Where(c => c.UserName.Contains(nameFilter));
}
if (minMedals > 0)
{
result = result.Where(c => c.AccessFailedCount >= minMedals);
}
return result;
}
}
}
}
>Solution :
IQueryable‘s and IEnumerables are lazy, so the actual work will happen only when the materializing operation is invoked (ToList, Count, Any etc.). Your using block ends before the materialization happens so it will lead to disposal of the context. I.e.
using (var factory = _contextFactory.CreateDbContext())
{
// ...
return result; // the returned to the caller query will have disposed context.
}
One thing you can do is to materialize before the disposal. For example:
@codes {
List<AppUser> FilteredCountries
{
get
{
using (var factory = _contextFactory.CreateDbContext())
{
var itemsQueryable = factory.Set<AppUser>().AsQueryable();
var result = itemsQueryable?.Where(c => c.AccessFailedCount <= maxMedals);
if (!string.IsNullOrEmpty(nameFilter))
{
result = result.Where(c => c.UserName.Contains(nameFilter));
}
if (minMedals > 0)
{
result = result.Where(c => c.AccessFailedCount >= minMedals);
}
return result.ToList();
}
}
}
}