ToAsyncEnumerable().Single()与SingleAsync() [英] ToAsyncEnumerable().Single() vs SingleAsync()
问题描述
我以独立于EF-Core的方式构造和执行查询,因此我依靠IQueryable<T>
来获得所需的抽象级别.我用等待的ToAsyncEnumerable().Single()
呼叫替换了等待的SingleAsync()
呼叫.我还将ToListAsync()
呼叫替换为ToAsyncEnumerable().ToList()
呼叫.但是我只是碰巧遇到了ToAsyncEnumerable()
方法,所以我不确定我是否正确使用了它.
I'm constructing and executing my queries in a way that's independent of EF-Core, so I'm relying on IQueryable<T>
to obtain the required level of abstraction. I'm replacing awaited SingleAsync()
calls with awaited ToAsyncEnumerable().Single()
calls. I'm also replacing ToListAsync()
calls with ToAsyncEnumerable().ToList()
calls. But I just happened upon the ToAsyncEnumerable()
method so I'm unsure I'm using it correctly or not.
要弄清楚我要指的是哪种扩展方法,它们的定义如下:
To clarify which extension methods I'm referring to, they're defined as follows:
-
在
-
SingleAsync
和ToListAsync
. -
ToAsyncEnumerable
是在System.Interactive.Async
程序集的System.Linq
命名空间中的AsyncEnumerable
类上定义的.
Microsoft.EntityFrameworkCore
名称空间和程序集的EntityFrameworkQueryableExtensions
类上定义了SingleAsync
andToListAsync
are defined on theEntityFrameworkQueryableExtensions
class in theMicrosoft.EntityFrameworkCore
namespace and assembly.ToAsyncEnumerable
is defined on theAsyncEnumerable
class in theSystem.Linq
namespace in theSystem.Interactive.Async
assembly.
当查询针对EF-Core运行时,调用ToAsyncEnumerable().Single()/ToList()
与SingleAsync()/ToListAsync()
在功能和性能上是否等效?如果不是,那么它们有何不同?
When the query runs against EF-Core, are the calls ToAsyncEnumerable().Single()/ToList()
versus SingleAsync()/ToListAsync()
equivalent in function and performance? If not then how do they differ?
推荐答案
对于返回序列的方法(例如ToListAsync
,ToArrayAsync
),我预计不会有所不同.
For methods returning sequence (like ToListAsync
, ToArrayAsync
) I don't expect a difference.
但是对于单值返回方法(First
,FirstOrDefault
,Single
,Min
,Max
,Sum
等的异步版本)肯定会有区别.这与在IQueryable<T>
与IEnumerable<T>
上执行这些方法的区别相同.在前一种情况下,它们通过数据库查询返回给客户端一个值来处理,而在后一种情况下,整个结果集将被返回给客户端并在内存中进行处理.
However for single value returning methods (the async versions of First
, FirstOrDefault
, Single
, Min
, Max
, Sum
etc.) definitely there will be a difference. It's the same as the difference by executing those methods on IQueryable<T>
vs IEnumerable<T>
. In the former case they are processed by database query returning a single value to the client while in the later the whole result set will be returned to the client and processed in memory.
因此,虽然通常来说,抽象EF Core的想法很好,但由于IQueryable<T>
的异步处理不是标准的,它将导致IQueryable<T>
的性能问题,并且转换为IEnumerable<T>
会更改执行上下文,因此实现单值返回LINQ方法的说明.
So, while in general the idea of abstracting EF Core is good, it will cause performance issues with IQueryable<T>
because the async processing of queryables is not standartized, and converting to IEnumerable<T>
changes the execution context, hence the implementation of single value returning LINQ methods.
P.S.通过标准化,我的意思是. IQueryable
的同步处理由IQueryProvider
(System.Core.dll
程序集中的System.Linq
命名空间的 standard 接口)和Execute
方法提供.异步处理将需要引入另一个类似于EF Core 自定义 IAsyncQueryProvider
的标准接口(在Microsoft.EntityFrameworkCore.dll
程序集中的Microsoft.EntityFrameworkCore.Query.Internal
名称空间内).我想这需要BCL团队的合作/批准并需要时间,这就是为什么他们决定暂时采用自定义方式的原因.
P.S. By standardization I mean the following. The synchronous processing of IQueryable
is provided by IQueryProvider
(standard interface from System.Linq
namespace in System.Core.dll
assembly) Execute
methods. Asynchronous processing would require introducing another standard interface similar to EF Core custom IAsyncQueryProvider
(inside Microsoft.EntityFrameworkCore.Query.Internal
namespace in Microsoft.EntityFrameworkCore.dll
assembly). Which I guess requires cooperation/approval from the BCL team and takes time, that's why they decided to take a custom path for now.
这篇关于ToAsyncEnumerable().Single()与SingleAsync()的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!