我正在以獨立於EF-Core的方式構建和執行查詢,所以我依靠IQueryable<T>
來獲得所需的抽象級別。我正在用等待的SingleAsync()
替換等待的SingleAsync()
調用ToAsyncEnumerable().Single()
調用。我也用ToListAsync()
ToAsyncEnumerable().ToList()
調用替換ToListAsync()
ToAsyncEnumerable().ToList()
調用。但我剛發生在ToAsyncEnumerable()
方法上,所以我不確定我是否正確使用它。
為了澄清我所指的擴展方法,它們的定義如下:
SingleAsync
和ToListAsync
在Microsoft.EntityFrameworkCore
命名空間和程序集中的EntityFrameworkQueryableExtensions
類上定義。 ToAsyncEnumerable
在System.Interactive.Async
程序集的System.Linq
命名空間中的AsyncEnumerable
類上定義。 當查詢針對EF-Core運行時,調用ToAsyncEnumerable().Single()/ToList()
與SingleAsync()/ToListAsync()
的功能和性能等效嗎?如果沒有,那麼它們有何不同?
對於返回序列的方法(如ToListAsync
, ToArrayAsync
),我不希望有任何區別。
但是對於單值返回方法( First
, FirstOrDefault
, Single
, Min
, Max
, Sum
等的異步版本)肯定會有區別。通過在IQueryable<T>
vs IEnumerable<T>
上執行這些方法,它與差異相同。在前一種情況下,它們由數據庫查詢處理,將單個值返回給客戶端,而在後一種情況下,整個結果集將返回到客戶端並在內存中處理。
因此,雖然通常抽象EF Core的想法很好,但它會導致IQueryable<T>
性能問題,因為可查詢的異步處理不是標準化的,並且轉換為IEnumerable<T>
改變執行上下文,因此實現單值返回LINQ方法。
PS標準化我指的是以下內容。 IQueryable
的同步處理由IQueryProvider
( System.Core.dll
程序集中的System.Linq
命名空間的標準接口)提供Execute
方法。異步處理需要引入另一個類似於EF Core 自定義 IAsyncQueryProvider
標準接口(在Microsoft.EntityFrameworkCore.dll
程序IAsyncQueryProvider
Microsoft.EntityFrameworkCore.Query.Internal
命名空間內)。我想這需要BCL團隊的合作/批准並需要時間,這就是為什麼他們現在決定採取自定義路徑。
根據EF Core的官方Microsoft文檔(所有版本,包括當前的2.1版本):
此API支持Entity Framework Core基礎結構,不能直接在您的代碼中使用。此API可能會在將來的版本中更改或刪除。
資料來源: https : //docs.microsoft.com/en-us/dotnet/api/microsoft.entityframeworkcore.query.internal.asynclinqoperatorprovider.toasyncenumerable?view = muscle 1-2
ps我個人發現它與AutoMapper工具相結合有問題(至少在版本6.2.2之前) - 它只是不映射IAsyncEnumerable類型的集合(與IEnumerable不同,AutoMapper可以無縫地工作)。