【问题标题】:EF core ToAsyncEnumerable and AsAsyncEnumerable ends with System.ObjectDisposedException [duplicate]EF 核心 ToAsyncEnumerable 和 AsAsyncEnumerable 以 System.ObjectDisposedException 结尾 [重复]
【发布时间】:2022-02-01 01:31:50
【问题描述】:

我正在开发 xamarin 项目并使用 Entity Framework Core 访问数据库。我知道这不是一个好的解决方案,但我决定不使用应用程序服务器。

DAL 层使用存储库模式,BL 层使用带有映射器的外观模式。 在 DAL 层上,我想创建实体的 IAsyncEnumerable,在 BL 上,我想创建模型的 IAsyncEnumerable。

第一个和第二个示例不起作用,它以 System.ObjectDisposedException “无法访问已释放的上下文实例...”结束,为什么? ToList() 效果很好,ToListAsync() 效果很好。

以 System.ObjectDisposedException 结束

public IAsyncEnumerable<TaskEntity> GetTasksByTaskGroupIdAndKanbanStateAsync(Guid taskGroupId, string kanbanStateName, CancellationToken token)
        {
            using (WorkManagerDbContext dbContext = IdbContextFactory.CreateDbContext())
            {
                return dbContext.TaskSet.AsQueryable().Where(s => s.TaskGroup.Id == taskGroupId)
    .Where(s => s.State.Name == kanbanStateName).ToAsyncEnumerable();
            }
        }

以 System.ObjectDisposedException 结束

public IAsyncEnumerable<TaskEntity> GetTasksByTaskGroupIdAndKanbanStateAsync(Guid taskGroupId, string kanbanStateName, CancellationToken token)
        {
            using (WorkManagerDbContext dbContext = IdbContextFactory.CreateDbContext())
            {
                return dbContext.TaskSet.AsQueryable().Where(s => s.TaskGroup.Id == taskGroupId).
    Where(s => s.State.Name == kanbanStateName).AsAsyncEnumerable();
            }
        }

工作解决方案,但我不知道它是否是好的解决方案。

public IAsyncEnumerable<TaskEntity> GetTasksByTaskGroupIdAndKanbanStateAsync(Guid taskGroupId, string kanbanStateName, CancellationToken token)
        {
            using (WorkManagerDbContext dbContext = IdbContextFactory.CreateDbContext())
            {
                return dbContext.TaskSet.AsQueryable().Where(s => s.TaskGroup.Id == taskGroupId)
                    .Where(s => s.State.Name == kanbanStateName).ToList().ToAsyncEnumerable();
            }
        }

【问题讨论】:

  • 您在 using 子句中构建它们,然后将它们从其中返回,这会在集合实际水合之前处理上下文对象。
  • 使 WorkManagerDbContext 限定在容器内,然后删除 using 语句。

标签: c# asynchronous entity-framework-core repository-pattern iasyncenumerable


【解决方案1】:

发生这种情况是因为 .ToAsyncEnumerable() 将在您使用对象(延迟加载)时执行 db 调用。 ToList() 将立即执行 db 调用。因此,当您在 using 语句中使用 this 时,会在返回返回对象时释放 DbContext。 .ToList() 在这种情况下是正确的解决方案。

但是,我对您创建和处理 DbContext 的方法存有疑问,因为它可能会在以后导致其他问题(例如更新在另一个上下文实例中跟踪的对象等)。此外,您还会失去一些好处,例如缓存结果。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-12-08
    • 1970-01-01
    • 1970-01-01
    • 2019-06-10
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多