我正在嘗試從具有注入 DbContext 的范圍后臺服務中獲取過去一小時內的 CheckIn 數量。
以下查詢按預期作業。
var checkins = _dbContext.CheckIns.ToList();
var checkinList = checkins.Where(x => x.LogInTimeStamp.ToUniversalTime() > DateTime.UtcNow.AddHours(-1));
var checkinCount = checkins.Count(x => x.LogInTimeStamp.ToUniversalTime() > DateTime.UtcNow.AddHours(-1));
由于我想保持干凈,我嘗試將其寫在一行中:
var oneLineCountTest = _dbContext.CheckIns.Count(x => x.LogInTimeStamp.ToUniversalTime() > DateTime.UtcNow.AddHours(-1));
var oneLineCountTest2 = (int?)_dbContext.CheckIns.Count(x => x.LogInTimeStamp.ToUniversalTime() > DateTime.UtcNow.AddHours(-1)) ?? 0;
這兩行都從 EFCore 回傳 InvalidOperationException,我不明白為什么。任何人都有解釋或解決方案?
Exception thrown: 'System.Net.Sockets.SocketException' in System.Net.Sockets.dll
Exception thrown: 'System.OperationCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.OperationCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.OperationCanceledException' in System.Net.Http.dll
Exception thrown: 'System.OperationCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Net.Http.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Net.Http.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Net.Http.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.Threading.Tasks.TaskCanceledException' in System.Private.CoreLib.dll
Exception thrown: 'System.InvalidOperationException' in Microsoft.EntityFrameworkCore.dll
謝謝
uj5u.com熱心網友回復:
注意本地查詢(Linq to Objects)和解釋查詢(Linq to Entities)之間的區別。
您的第一個代碼片段(有效的代碼片段)使用解釋查詢來構建串列。您向資料庫引擎詢問元素集合,然后它們被回傳并具體化為一個串列(ToList() 呼叫進行具體化)。然后在該串列上進行本地查詢,這是可能的,因為該串列是本地物件(在記憶體中)。
第二個代碼片段是不同的。您只是在執行解釋查詢(使用 Linq to Entities)。這意味著您要求資料庫引擎執行所有查詢:計算滿足特定規則的元素數量。只有當 Linq to Entities 能夠將 SQL 中的查詢轉換為由資料庫引擎執行時,它才會起作用。這可能在這里失敗。
罪魁禍首可能是使用 AddDays() 方法(請參閱最后的第一個鏈接)。
請記住:
- Linq to Object 使用委托在 IEnumerable 上作業。
- Linq to Entities 使用運算式樹在 IQueryable 上作業。
因此,在您的情況下,解釋查詢中使用的代碼可能無法轉換為 SQL。
要檢查這一點,請嘗試簡化(即使它沒有功能意義)用作 Count 引數的 lambda 中的代碼,以查看是否沒有更多例外。
看:
- 執行 Select 時在 EF Core 3 中將日期添加到日期時間
- 不支持 Linq-to-EF DateTime.ToLocalTime
- 物體框架查詢中的 Datetime.UtcNow 與 C# IL 中的 DateTime.UtcNow 評估不同
uj5u.com熱心網友回復:
如果您嘗試此查詢,它不會發出任何例外
var dateTimeNow= DateTime.AddHours(-1);
Var oneLineCountTest = _dbContext.CheckIns.Count(x => x.LogInTimeStamp > DateTimeNow);
這意味著 EF 轉換器無法將 ToUniversalTime() 轉換為 SQL 腳本,這就是您的例外情況。使用 ToList() 后,所有資料都將移動到 Web 服務器,您可以使用任何對 c# 合法的代碼。我認為,由于您使用的是差異而不是時間,因此您可以計算差異而不轉換為 UTC 時間,只要您的應用程式不在世界各地使用。
轉載請註明出處,本文鏈接:https://www.uj5u.com/qukuanlian/342485.html
上一篇:將資訊從AJAX傳遞到控制器類
