非同步程式設計

非同步作業可避免在資料庫中執行查詢時封鎖執行緒。 非同步作業對於在豐富的用戶端應用程式中保持回應式 UI 很重要,而且也可以在 Web 應用程式中增加輸送量,讓執行緒釋出線程來服務 Web 應用程式中的其他要求。

在 .NET 標準之後,EF Core 會提供執行 I/O 之所有同步方法的非同步對應專案。 這些效果與同步方法相同,而且可以搭配 C# asyncawait 關鍵字使用。 例如,您可以使用 DbCoNtext.SaveChanges,而不是使用 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 運算子只能在 EF 查詢上使用 - 您無法搭配用戶端 LINQ to Objects 查詢使用它們。 若要在 EF 外部執行用戶端非同步 LINQ 作業,請使用 System.Linq.Async 套件 ;此套件對於在無法轉譯供伺服器評估的用戶端上執行作業特別有用。

在 EF Core 6.0 和更低版本中,參考 System.Linq.Async 很不幸會導致套用至 EF DbSets 之 LINQ 運算子的模棱兩可調用編譯錯誤;這會使 EF 和 System.Linq.Async 相同的專案中難以使用。 若要解決此問題,請將 新增 AsQueryable 至 DbSet:

var groupedHighlyRatedBlogs = await context.Blogs
    .AsQueryable()
    .Where(b => b.Rating > 3) // server-evaluated
    .AsAsyncEnumerable()
    .GroupBy(b => b.Rating) // client-evaluated
    .ToListAsync();