【问题标题】:What do I replace IQueryable with for Async operations? [duplicate]对于异步操作,我应该用什么替换 IQueryable? [复制]
【发布时间】: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&lt;T&gt;)。
  • 谢谢@Euphoric 和Ivan Stoev - 问题与我模拟变量的方式有关。有了这个观察,很容易找到一个已经存在的答案,所以我会将我自己的问题标记为重复(或删除它)......

标签: c# linq entity-framework-core


【解决方案1】:

IQueryable&lt;T&gt; 是一种构造,使您能够在数据库处理查询之前构建查询。没有什么异步的。涉及异步的部分是当您实际将查询发送到数据库并等待响应时(当您使用 SingleAsync() 时会发生这种情况)。那时,您不再拥有IQueryable&lt;T&gt;,因为现在它是一个实际的结果集。

【讨论】:

  • 这并没有解释为什么 OP 会收到他们遇到的错误或如何纠正它。该问题表明他们了解IQueryable&lt;T&gt; 用于构建查询,而不是执行它,因为他们询问了如何在不具体化查询结果的情况下执行他们所要求的操作。
猜你喜欢
  • 1970-01-01
  • 2015-07-01
  • 2014-11-27
  • 1970-01-01
  • 2016-08-11
  • 2010-12-13
  • 1970-01-01
  • 1970-01-01
  • 2019-09-04
相关资源
最近更新 更多