EF 核心 ToAsyncEnumerable 和 AsAsyncEnumerable 以 System.ObjectDisposedException 结尾

EF core ToAsyncEnumerable and AsAsyncEnumerable ends with System.ObjectDisposedException

我正在研究 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();
            }
        }

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

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