共用方式為


異步程序設計

異步作可避免在資料庫中執行查詢時封鎖線程。 異步操作對於保持豐富客戶端應用程式中的回應式UI非常重要,也可以在網路應用程式中增加輸送量,因為它們能夠釋放線程來處理其他請求。

依循 .NET 標準,EF Core 提供執行 I/O 的所有同步方法的異步對應方法。 這些效果與同步方法相同,而且可與 C# asyncawait 關鍵詞搭配使用。 例如,您可以使用 DbContext.SaveChangesAsync,而不是使用 DbContext.SaveChanges,因為後者在執行資料庫 I/O 時會封鎖線程:

var blog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(blog);
await context.SaveChangesAsync();

如需詳細資訊,請參閱 一般 C# 異步程式設計檔

警告

EF Core 不支援在相同的內容實例上執行多個平行作業。 您應該一律等候作業完成,再開始下一個作業。 這通常是透過在每個異步作業上使用 await 關鍵詞來完成。

警告

Microsoft.Data.SqlClient 的異步實作不幸有一些已知問題(例如 #593#601等)。 如果您看到非預期的效能問題,請嘗試改用同步命令執行,尤其是在處理大型文字或二進位值時。

注意

EF Core 會將取消令牌傳遞至使用中的基礎資料庫提供者(例如Microsoft.Data.SqlClient)。 這些令牌可能被接受,也可能不被接受,請參閱您的資料庫提供者的文件。

異步 LINQ 運算子

為了支援以異步方式執行 LINQ 查詢,EF Core 提供一組異步擴充方法,以執行查詢並傳回結果。 這些與標準、同步 LINQ 運算子的相對應運算子包括 ToListAsyncSingleAsyncAsAsyncEnumerable等:

var blogs = await context.Blogs.Where(b => b.Rating > 3).ToListAsync();

請注意,某些 LINQ 運算子沒有異步版本,例如 WhereOrderBy,因為這些運算符只會建置 LINQ 運算式樹狀結構,而且不會造成查詢在資料庫中執行。 只有導致查詢執行的運算子才有異步對應版本。

重要

EF Core 異步擴充方法定義於 Microsoft.EntityFrameworkCore 命名空間中。 必須匯入此命名空間,才能使用方法。

用戶端異步 LINQ 運算符

在某些情況下,您可能會想要將用戶端 LINQ 運算子套用至從資料庫傳回的結果;當您需要執行無法轉譯為 SQL 的作業時,尤其需要此功能。 針對這類情況,請使用 AsAsyncEnumerable 在資料庫上執行查詢,並透過產生的 IAsyncEnumerable<T>繼續撰寫用戶端 LINQ 運算符。 例如,下列會在 EF LINQ 查詢的異步結果上執行本機 .NET 函式:

var blogs = context.Blogs
    .Where(b => b.Rating > 3) // server-evaluated (translated to SQL)
    .AsAsyncEnumerable()
    .Where(b => SomeLocalFunction(b)); // client-evaluated (in .NET)

await foreach (var blog in blogs)
{
    // ...
}

注意

在 .NET 10 中引進了透過 IAsyncEnumerable<T> 的 LINQ 運算符。 使用舊版 .NET 時,請參考 System.Linq.Async 套件。