DBContext : Getting disposed without calling Dispose(). Not using a using statement

asp.net-core c# dependency-injection entity-framework-core

Question

I am trying to call some queries on my dbcontext. I have saved the data in the DB, and am now trying to extract the data again in a thread to do further processing, but unable to do so. The dbcontext comes up as disposed.

I have tried modifying the service lifetime of the dbcontext to singleton and transient from default scoped as well as changed the lifetime of classed calling the dbcontext to transient.

Services Addition :

public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<PearlIDPContext>(options => options.UseMySQL(Configuration.GetConnectionString("IDPDatabase")), optionsLifetime: ServiceLifetime.Transient);
    services.AddScoped<IScanDataRepository, ScanDataRepository>();
    services.AddScoped<IOperationsRepository, OperationHistoryRepository>();
    services.AddScoped<IExtractedDataRepository, ExtractedDataRepository>();
    services.AddScoped<IExtractedColorsRepository, ExtractedColorsRepository>();
    services.AddScoped<IRejectionsRepository, RejectionsRepository>();
    services.AddScoped<IStartProcess, StartProcess>();
}

Db modification class :

public class ScanDataRepository : IScanDataRepository
{
    private readonly PearlIDPContext context;

    public ScanDataRepository(PearlIDPContext context)
    {
        this.context = context;
    }
    public async Task<ScanData> AddAsync(ScanData scan) [modified]
    {
        context.ScanData.Add(scan);
        await context.SaveChangesAsync();
        return scan;
    }
    public ScanData GetScanData(string pearlId)
    {
       return context.ScanData.FirstOrDefault(o => o.PearlId == pearlId);
    }
}

calls to modification class:

scanDataRepository.AddAsync(scanData);

try
{
    Logger.WriteToLogFile("Fetching Scan details from database for pearlID : " + pearlId, pearlId);

    scanData = scanDataRepository.GetScanData(pearlId); // this is line 39
    int id = scanData.ScanId;
    Logger.WriteToLogFile("Fetching Scan details from database successful for pearlID : " + pearlId + ". DB table id : " + id, pearlId);
}
catch (Exception ex)
{
    Logger.WriteToErrorFile("Error getting data from databse. Pearl ID : " + pearlId + ". Error : " + ex.ToString());
}

Error getting data from database. Pearl ID : PI09889. Error : System.ObjectDisposedException: Cannot access a disposed object. A common cause of this error is disposing a context 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, or wrapping the context 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: 'PearlIDPContext'. 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.get_StateManager() at Microsoft.EntityFrameworkCore.Query.QueryContext.BeginTrackingQuery() at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider._TrackEntities[TOut,TIn](IEnumerable`1 results, QueryContext queryContext, IList`1 entityTrackingInfos, IList`1 entityAccessors)+MoveNext() at Microsoft.EntityFrameworkCore.Query.Internal.LinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.MoveNext() at System.Linq.Enumerable.TryGetFirst[TSource](IEnumerable`1 source, Boolean& found) at System.Linq.Enumerable.First[TSource](IEnumerable`1 source) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.<>c__DisplayClass15_1`1.b__0(QueryContext qc) at Microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.Execute[TResult](Expression query) at Microsoft.EntityFrameworkCore.Query.Internal.EntityQueryProvider.Execute[TResult](Expression expression) at System.Linq.Queryable.FirstOrDefault[TSource](IQueryable`1 source, Expression`1 predicate) at MyndIT.Models.ScanDataRepository.GetScanData(String pearlId) in D:\Projects\Github\PearlIDP\MyndIT\Models\ScanDataRepository.cs:line 33 at MyndIT.StartProcess.ProcessStart(String pearlId) in D:\Projects\Github\PearlIDP\MyndIT\StartProcess.cs:line 39

1
0
11/14/2019 12:43:17 PM

Popular Answer

Please make sure that the code where this line is found:

scanDataRepository.Add(scanData);

Is awaited properly. If this code is executed inside a method that returns a Task, and that task is not awaited properly, then the database could end up being disposed, because the caller has already finished, even though your database operations are still pending.

0
11/11/2019 9:16:48 AM


Related Questions





Related

Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow