EF核心DbContext ObjectDisposedException

具有EF核心2.2和.net核心2.2,我正在努力解决ObjectDisposedException问题,例如: herehere

一些事实:

  • 我所有的服务都已注册为Transient,与使用AddDbContext()的DbContext相同
  • 使用DI注入DbContext实例
  • 堆栈跟踪中提到的所有函数均为async / await

我觉得我这里缺少明显的东西,但是我已经花了2-3天了,没有运气

堆栈跟踪:

microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware [8] - An unhandled exception has occurred while executing the request. 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: 'BaseContext'.
   at microsoft.EntityFrameworkCore.DbContext.CheckDisposed()
   at microsoft.EntityFrameworkCore.DbContext.get_DbContextDependencies()
   at microsoft.EntityFrameworkCore.DbContext.microsoft.EntityFrameworkCore.Internal.IDbContextDependencies.get_QueryProvider()
   at microsoft.EntityFrameworkCore.Query.ExpressionVisitors.Internal.ParameterExtractingExpressionVisitor..ctor(IEvaluatableExpressionFilter evaluatableExpressionFilter,IParameterValues parameterValues,IDiagnosticsLogger`1 logger,DbContext context,Boolean parameterize,Boolean generateContextaccessors)
   at microsoft.EntityFrameworkCore.Query.Internal.QueryModelGenerator.ExtractParameters(IDiagnosticsLogger`1 logger,Expression query,Boolean generateContextaccessors)
   at microsoft.EntityFrameworkCore.Query.Internal.QueryCompiler.ExecuteAsync[TResult](Expression query)
   at microsoft.EntityFrameworkCore.Query.Internal.EntityQueryable`1.System.Collections.Generic.IAsyncEnumerable<TResult>.GetEnumerator()
   at System.Linq.AsyncEnumerable.Aggregate_[tsource,Taccumulate,TResult](IAsyncEnumerable`1 source,Taccumulate seed,Func`3 accumulator,Func`2 resultSelector,CancellationToken cancellationToken) in D:\a\1\s\Ix.NET\Source\System.Interactive.Async\Aggregate.cs:line 118
   at Sample.Infrastructure.Tasks.TagEventTypetasks.GetallAsync() in ~root\Sample.API\Sample.Infrastructure\Tasks\TagEventTypetasks.cs:line 24
   at Sample.API.Helpers.GraphHelpers.GetallTagEventTypesWithCacheAsync() in ~root\Sample.API\Sample.API\Helpers\GraphHelpers.cs:line 45
   at Sample.API.Controllers.GraphController.GetTagEventTypeTimesAsync() in ~root\Sample.API\Sample.API\Controllers\GraphController.cs:line 59
   at lambda_method(Closure,Object )
   at microsoft.Extensions.Internal.ObjectMethodExecutorAwaitable.Awaiter.GetResult()
   at microsoft.AspNetCore.Mvc.Internal.actionmethodExecutor.AwaitableObjectResultExecutor.Execute(IactionResultTypeMapper mapper,ObjectMethodExecutor executor,Object controller,Object[] arguments)
   at System.Threading.Tasks.Valuetask`1.get_Result()
   at microsoft.AspNetCore.Mvc.Internal.ControlleractionInvoker.InvokeactionmethodAsync()
   at microsoft.AspNetCore.Mvc.Internal.ControlleractionInvoker.InvokeNextactionFilterAsync()
   at microsoft.AspNetCore.Mvc.Internal.ControlleractionInvoker.Rethrow(actionExecutedContext context)
   at microsoft.AspNetCore.Mvc.Internal.ControlleractionInvoker.Next(State& next,Scope& scope,Object& state,Boolean& isCompleted)
   at microsoft.AspNetCore.Mvc.Internal.ControlleractionInvoker.InvokeInnerFilterAsync()
   at microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeNextResourceFilter()
   at microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Rethrow(ResourceExecutedContext context)
   at microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.Next(State& next,Boolean& isCompleted)
   at microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeFilterPipelineAsync()
   at microsoft.AspNetCore.Mvc.Internal.ResourceInvoker.InvokeAsync()
   at microsoft.AspNetCore.Routing.EndpointMiddleware.Invoke(HttpContext httpContext)
   at microsoft.AspNetCore.Routing.EndpointRoutingMiddleware.Invoke(HttpContext httpContext)
   at microsoft.AspNetCore.Diagnostics.StatusCodePagesMiddleware.Invoke(HttpContext context)
   at microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware.Invoke(HttpContext context)

为获得完全透明,下面是堆栈跟踪中提到的方法:

GraphController.cs:

[HttpGet("tagEventTypeTimes")]
public async Task<actionResult<List<TagEventTypeResultDto>>> GetTagEventTypeTimesAsync()
{
    return await _graphHelpers.GetallTagEventTypesWithCacheAsync();
}

GraphHelpers.cs:

public async Task<List<TagEventType>> GetallTagEventTypesWithCacheAsync()
{
    string tagEventTypesKey = "tagEventTypes";
    List<TagEventType> tagEventTypes;
    if (!_cache.TryGetvalue<List<TagEventType>>(tagEventTypesKey,out tagEventTypes))
    {
        tagEventTypes = await _tagEventTypetasks.GetallAsync();
        _cache.Set<List<TagEventType>>(tagEventTypesKey,tagEventTypes,_memCacheOptions);
    }

    return tagEventTypes;
}

TagEventTypetasks.cs:

public class TagEventTypetasks : ITagEventTypetasks
{
    private readonly BaseContext _context;

    public TagEventTypetasks(BaseContext context)
    {
        _context = context;
    }

    public async Task<List<TagEventType>> GetallAsync()
    {
        return await _context.TagEventType.OrderByDescending(x => x.Id).AsnoTracking().ToListAsync();
    }
}

BaseContext.cs:

public class BaseContext : DbContext
{
    private readonly ILoggerFactory _logger;

    public BaseContext(DbContextOptions<BaseContext> options,ILoggerFactory logger) : base(options)
    {
        _logger = logger;
    }

    protected override void Onconfiguring(DbContextOptionsBuilder optionsBuilder)
    {
        optionsBuilder.UseLoggerFactory(_logger);
    }

    public DbSet<Patient> Patient { get; set; }
    public DbSet<Room> Room { get; set; }
    public DbSet<Tag> Tag { get; set; }
    public DbSet<TagEvent> TagEvent { get; set; }
    public DbSet<TagEventType> TagEventType { get; set; }
    public DbSet<TagLocation> TagLocation { get; set; }
    public DbSet<TagRegistration> TagRegistration { get; set; }
    public DbSet<User> User { get; set; }

    protected override void OnmodelCreating(ModelBuilder builder)
    {
        builder.ApplyConfiguration(new PatientConfiguration());
        builder.ApplyConfiguration(new TagConfiguration());
        builder.ApplyConfiguration(new TagRegistrationconfiguration());
        builder.ApplyConfiguration(new TagEventConfiguration());
        builder.ApplyConfiguration(new TagEventTypeConfiguration());
        builder.ApplyConfiguration(new TagLocationconfiguration());
        builder.ApplyConfiguration(new RoomConfiguration());
    }
}

更新: 添加了启动相关代码

services.AddDbToServices(Configuration.getconnectionString("DefaultConnection"));

public static void AddDbToServices(this IServiceCollection services,string connectionString)
{
    services.AddDbContext<BaseContext>(options => options.UseFirebird(connectionString),ServiceLifetime.Transient);
}

UPDATE2

增加了整个TagEventTypetasks

UPDATE3

附加服务注册 我正在使用此lib,但是我尝试使用AddTransient()->手动注册所有服务也没有帮助

var assembliesToScan = new[]
{
    Assembly.GetExecutingAssembly(),Assembly.Getassembly(typeof(Patient)),Assembly.Getassembly(typeof(PatientTasks))
};

services
    .RegisterAssemblyPublicNonGenericClasses(assembliesToScan)
    .AsPublicImplementedInterfaces(ServiceLifetime.Transient);
soei4366 回答:EF核心DbContext ObjectDisposedException

这看起来像是依赖项注入问题。

我认为_graphHelpers布置了上下文,并且下次执行该动作时,控制器将使用非临时性_graphHelpers,它保留了旧的,已布置的上下文。

甚至可能是控​​制器在Dispose()上调用_graphHelpers


一些DI示例

这是Get Started with ASP.NET Core and Entity Framework 6

的设置
(...)
services.AddScoped<SchoolContext>(_ => new SchoolContext(Configuration.GetConnectionString("DefaultConnection")

Tutorial: Get started with EF Core in an ASP.NET MVC web app使用AddDbContext请注意,此示例适用于.NET Core 2.2,而非3.0。

(...)
services.AddDbContext<SchoolContext>(options =>
    options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection")));

这是Configuring a DbContext

中的配置
public void ConfigureServices(IServiceCollection services)
{
    services.AddDbContext<BloggingContext>(options => options.UseSqlite("Data Source=blog.db"));
}

没有DI解决方案

您可以使用新的上下文而不是_context来获取数据。

public async Task<List<TagEventType>> GetAllAsync()
{
    // If you want DI,then do this only Temporarily,just for a diagnosis.
    using (var db = new InverterContext("connString")) 
    {
       return await db.TagEventType.OrderByDescending(x => x.Id).AsNoTracking().ToListAsync();
    }
}
本文链接:https://www.f2er.com/3155898.html

大家都在问