Nai*_*tel 4 c# tolist async-await entity-framework-core iasyncenumerable
函数需要返回Task<List<Record>>
以下两个选项都返回Task<List<Record>>,哪个更有效?这里有标准的方法吗?
选项1 :
Task<List<Record>> GetRecords()
{
return
DbContext.Set<Record>.Where(predicate).ToListAsync();
}
Run Code Online (Sandbox Code Playgroud)
选项 2:
Task<List<Record>> GetRecords()
{
return
DbContext.Set<Record>.Where(predicate).AsAsyncEnumerable().ToList();
}
Run Code Online (Sandbox Code Playgroud)
Tob*_*s J 19
ToListAsync()没有人真正解释过和之间的区别AsAsyncEnumerable()。
ToListAsync()会将查询的所有结果提取到内存中,然后将结果集合作为单个List<T>对象返回。它将异步执行此操作,以便不会阻塞 I/O,但在所有结果可用之前不会返回任何内容。
AsAsyncEnumerable()将“产生”每个可用的结果。在OP的示例中,他们只是调用ToList(),所以结果是相同的。但是,从 C# 8.0 开始,您还可以使用“异步流”,例如await foreach,然后在返回时对每个实体进行操作。例如:
await foreach (var entity in DbContext.Set<Record>.Where(predicate).AsAsyncEnumerable())
{
// do something with entity...
}
Run Code Online (Sandbox Code Playgroud)
至于哪个“更好”,这取决于您的用例。如果您只是向调用者返回一些记录,ToListAsync()应该没问题。
但是,假设您的查询将返回 10,000 条记录。在对它们进行操作之前,您可能不想将所有这些存储在内存中,因为查询可能会运行很多秒甚至几分钟,并且会使用大量内存。
在这种情况下,最好使用异步流。这可能是你自己的async IAsyncEnumerable<T>方法,yield有它自己的结果。如果需要,您可以将它们链接在一起。
事实上,从 ASP.NET Core 6 开始,您可以直接从控制器方法返回一个IAsyncEnumerable<T>,它会将这些结果“流”回调用者。
这使得编写操作和/或返回大量记录的代码更加高效,因为它们永远不会被缓冲到内存中。
请注意,这是 .NET Core 3.x 之前的答案。
在下面 @IanKemp 的评论中查找更新。
选择选项 1ToListAsync作为明确提到的源代码AsAsyncEnumerable
这是一个内部 API,支持 Entity Framework Core 基础设施,并且不受与公共 API 相同的兼容性标准的约束。它可能会在任何版本中更改或删除,恕不另行通知。您应该极其谨慎地在代码中直接使用它,并且知道这样做可能会导致更新到新的 Entity Framework Core 版本时出现应用程序故障。
官方文档 提到
此 API 支持 Entity Framework Core 基础结构,并不适合直接在您的代码中使用。此 API 可能会在未来版本中更改或删除。
虽然 pfx 的现有答案对于 .NET Core 2.x 及更早版本仍然适用,但AsAsyncEnumerable已正式添加到 .NET Core 3.x 中。有关更多信息,请参阅 Ian Kemp 的评论。
| 归档时间: |
|
| 查看次数: |
6993 次 |
| 最近记录: |