假设我在数据库中有一个具有多个关系的Projects
表。我的C#代码的DB层中的各种不同查询都可能希望将此表与其他表连接起来。因此,我摘录了以下内容:
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的源才能用于Entity Framework异步操作。
显然,我不应该将IQueryable用作我的第一个QueryProject
抽象的返回类型。但是,我正在努力寻找可行的替代方案。我不希望在执行QueryProject
期间对实体进行任何数据库检索。我也对仅隐藏此错误却没有给我带来任何好处的黑客不感兴趣。我只是想抽象掉重复的代码。
.NET core 2.1是否支持某种类型的替代方案?
P.S。 Ivan Stoev提出了一个有效的担忧,问题可能出在我的单元测试中。这是我的模拟代码供参考(使用Moq):
mockServices.Setup(x => x.QueryProject(It.IsAny<SomeProjectAbstraction>()))
.Returns(new List<Project>
{
new Project
{
Name = ...
}
}.AsQueryable());
答案 0 :(得分:1)
IQueryable<T>
是一种结构,使您可以在数据库处理查询之前 建立查询。这没有什么不同步的。异步涉及的部分是当您实际将查询发送到数据库并等待响应时(使用SingleAsync()
时会发生这种情况)。那时,您不再拥有IQueryable<T>
,因为现在它是实际结果集。