【发布时间】:2019-01-20 05:49:36
【问题描述】:
假设我的数据库中有一个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 的源才能用于实体框架异步操作。
很明显,我不应该使用 IQueryable 作为我的第一个 QueryProject 抽象的返回类型。但是,我正在努力寻找可行的替代方案。在执行QueryProject 期间,我不希望对实体进行任何数据库检索。我也对简单地隐藏这个错误而不给我带来任何好处的黑客不感兴趣。我只是想抽象出重复的代码。
.NET core 2.1 是否支持某种类型的替代方案?
附: Ivan Stoev 提出了一个有效的担忧,即问题可能出在我的单元测试中。这是我的模拟代码供参考(使用 Moq):
mockServices.Setup(x => x.QueryProject(It.IsAny<SomeProjectAbstraction>()))
.Returns(new List<Project>
{
new Project
{
Name = ...
}
}.AsQueryable());
【问题讨论】:
-
直接在QueryProject中使用代码,代码是否有效?
-
"我的 单元测试" 出现以下错误,那么问题很可能不是由 EF Core 引起的,而是您的单元测试模拟了或者你在那里使用的任何东西(除了真正的 EF Core
IQueryable<T>)。 -
谢谢@Euphoric 和Ivan Stoev - 问题与我模拟变量的方式有关。有了这个观察,很容易找到一个已经存在的答案,所以我会将我自己的问题标记为重复(或删除它)......
标签: c# linq entity-framework-core