“ToListAsync()”和“AsAsyncEnumerable().ToList()”之间的区别

Posted

技术标签:

【中文标题】“ToListAsync()”和“AsAsyncEnumerable().ToList()”之间的区别【英文标题】:Difference between "ToListAsync()" and "AsAsyncEnumerable().ToList()" 【发布时间】:2019-10-04 04:21:45 【问题描述】:

函数需要返回Task<List<Record>> 以下两个选项都返回Task<List<Record>>,哪个更有效?这里有什么标准方法吗?

选项 1:

Task<List<Record>> GetRecords()

    return 
    DbContext.Set<Record>.Where(predicate).ToListAsync();


选项2:

Task<List<Record>> GetRecords()

    return
    DbContext.Set<Record>.Where(predicate).AsAsyncEnumerable().ToList();


【问题讨论】:

很有可能是同一个操作。 你能清楚这个 AsAsyncEnumerable 来自哪个命名空间/程序集吗?关于 C# 和 EF 版本?谷歌排名靠前的结果指向“可能在未来版本中删除”的老歌 @HenkHolterman 是的。我正在使用 EF Core 2.2。和 C# 7 【参考方案1】:

虽然 pfx 的现有答案对于 .NET Core 2.x 及更早版本仍然适用,但 AsAsyncEnumerable 已正式添加到 .NET Core 3.x 中。有关详细信息,请参阅 Ian Kemp 的评论。

【讨论】:

重述别人的评论,预计需要一些额外的信息。 @Rzassar 在 pfx 写他的帖子时,AsAsyncEnumerable 仍处于草稿状态。这就是我想指出的原因,它现在是一个官方功能,因此可以替代他的方法。 好的,请编辑您的答案,以便我为您投票:-)。 @Rzassar 好吧,在这方面,pfx 和我的回答都没有真正回答这个问题。实际的问题是,哪一个更有效。 pfx 声明,您根本不应该使用AsAsyncEnumerable,因为它是框架的内部方法。我已修改此说明,发现该声明不再反映最新技术。但最后,关于这两个变体中性能更高的原始问题仍然没有得到我们任何一个人的回答。【参考方案2】:

请注意,这是 .NET Core 3.x 之前的答案。 在下面@IanKemp 的评论中找到更新。

选择选项 1 ToListAsync,因为 source code 的 AsAsyncEnumerable 明确提到

这是一个支持 Entity Framework Core 的内部 API 基础设施,并且不受与相同的兼容性标准的约束 公共 API。它可能会被更改或删除,恕不另行通知 发布。您应该只在极端情况下直接在代码中使用它 小心并知道这样做会导致应用程序失败 更新到新的 Entity Framework Core 版本时。

official documentation 提及

此 API 支持 Entity Framework Core 基础架构,但不支持 旨在直接从您的代码中使用。此 API 可能会更改或被 在未来的版本中删除。

【讨论】:

谢谢@pfx 你推荐使用Task&lt;List&lt;Record&gt;&gt; GetRecords() var records = DbContext.Set&lt;Record&gt;.Where(predicate).ToList(); return Task.FromResult(records); @NaineshPatel 也避免在这里使用Task.FromResult 并通过ToListAsync 使用Entity Frameworkasync 功能。 从 EF 3.0.0 版开始,AsAsyncEnumerable 将成为完全公开的一等公民:github.com/aspnet/EntityFrameworkCore/commit/…

以上是关于“ToListAsync()”和“AsAsyncEnumerable().ToList()”之间的区别的主要内容,如果未能解决你的问题,请参考以下文章

为啥在获取 Users.ToListAsync() 不为空时会出现 SqlNullException

ToListAsync 抛出“值不能为空”。例外

如果我在未定义为任务的 IQueryable 上使用 await + ToListAsync() 是不是正确

entity.ToListAsync()。where或entity.Where()?

带有 DbSet 的 LINQ ToListAsync 表达式

EF6 两个上下文与具有两个等待的单个上下文