对于异步操作,我应该用什么替换 IQueryable?



假设我的数据库中有一个具有多个关系的Projects表。我的 c# 代码的数据库层中的各种不同查询都有兴趣将此表与其他表联接。所以我抽象出以下内容:

public IQueryable<Project> QueryProject(Project prj)
{
return Context.Projects.Where(p => p.id == prj.id);
}

。所以我可以在各种其他场景中重用此方法,例如...

_queryService.QueryProject(prj).Include(p => p.Users)

。或

_queryService.QueryProject(prj).Include(p => p.Artefacts)

。等。有一次,我决定使操作方法异步是一个好主意,因此我尝试以下方法:

await _queryService.QueryProject(prj).Include(p => p.Artefacts).SingleAsync();

但是,当我尝试异步使用QueryProject方法进行任何操作时,我从单元测试中得到以下错误:

源 IQueryable 不实现 IAsyncEnumerable。只有实现 IAsyncEnumerable 的源才能用于实体框架异步操作。

很明显,我不应该使用 IQueryable 作为我的第一个QueryProject抽象的返回类型。但是,我正在努力寻找可行的替代方案。我不希望在执行QueryProject期间对实体进行任何数据库检索。我也对简单地隐藏此错误而不会给我带来任何好处的黑客不感兴趣。我只是想抽象出重复的代码。

.NET Core 2.1 中是否支持某种类型的替代方案?

附言伊万·斯托耶夫提出了一个合理的担忧,即问题可能出在我的单元测试中。这是我的模拟代码供参考(使用最小起订量(:

mockServices.Setup(x => x.QueryProject(It.IsAny<SomeProjectAbstraction>()))
.Returns(new List<Project>
{
new Project
{
Name = ...
}
}.AsQueryable());
IQueryable<T>

是一种构造,使您能够在数据库处理查询之前构建查询。这些都不是异步的。异步涉及的部分是当您实际将查询发送到数据库并等待响应时(这就是使用SingleAsync()时发生的情况(。此时,您不再有IQueryable<T>,因为现在它是一个实际的结果集。

最新更新