簡體   English   中英

沒有值的 Linq 計數列表 InvalidOperationException

[英]Linq Count List InvalidOperationException on no values

我正在嘗試從具有注入 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

謝謝

注意本地查詢(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 中的代碼,以查看是否沒有更多異常。

看:

如果您嘗試此查詢,它不會發出任何異常

var dateTimeNow= DateTime.AddHours(-1);

Var oneLineCountTest = _dbContext.CheckIns.Count(x => x.LogInTimeStamp > DateTimeNow);

這意味着 EF 轉換器無法將 ToUniversalTime() 轉換為 SQL 腳本,這就是您的例外情況。 使用 ToList() 后,所有數據都將移動到 Web 服務器,您可以使用任何對 c# 合法的代碼。 我認為,由於您使用的是差異而不是時間,因此您可以計算差異而不轉換為 UTC 時間,只要您的應用程序不在世界各地使用。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM