前言
在 ASP.NET Core 中,EF Core 的 DI 通常是設定成 Scoped。
但 Blazor Server 的 Scoped 是以 SignalR Connection 來看的,所以並不是之前 ASP.NET Core 的每次 Request。
所以如果直接在 Blazor Server 中使用 EF Core 的 DbContext 時,有時會噴以下的錯誤,
Invalid attempt to call ReadAsync when reader is closed.
A second operation started on this context before a previous operation completed. This is usually caused by different threads using the same instance of DbContext. For more information on how to avoid threading issues with DbContext
解決方式
解法1 : 讓頁面繼承 OwningComponentBase
讓 Service 的生命週期變成是以 Page 為 Base ,也就是使用者切換頁面時,那個注入的服務才會 Release 掉。
1 | @inherits OwningComponentBase<SyncfusionHelpDeskService> |
但有這在同一個頁面中的 Method ,如果同時操作 async & sync 的 DbContext Method ,就有可能出現 Invalid attempt to call ReadAsync when reader is closed.
解法2 : 改用 Transient
解法3 : 要使用時,再透過 IServiceScopeFactory.CreateScope 建立
1 |
|
但如果有把 DbContext 直接回傳 IQueryable Bind 到 Blazor 控制項的話,也會噴 A second operation started on this context before a previous operation completed 的錯哦!
參考資料
Using Entity Framework in a Blazor Server Application
An Introduction to OwningComponentBase