2017-04-06 90 views
2

我的應用程序是一個ASP.NET Core 1.0 Web API。LINQ-Expression失敗,但foreach循環工作實體框架

我有以下LINQ的表達我的代碼:

int number = 0; 
var orders = await this.DataRepo.Where(data => data.number == number).ToListAsync(); 

如果我嘗試運行失敗,並給了我以下錯誤消息的代碼:

Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory:Error: An exception occurred in the database while iterating the results of a query. System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception: Der Wartevorgang wurde abgebrochen --- End of inner exception stack trace --- at System.Data.SqlClient.SqlCommand.<>c.b__107_0(Task`1 result) at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke() at System.Threading.Tasks.Task.Execute() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.d__20.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable.AsyncEnumerator.d__8.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.SelectAsyncEnumerable`2.SelectAsyncEnumerator.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.SelectAsyncEnumerable`2.SelectAsyncEnumerator.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.d__5.MoveNext() ClientConnectionId:64923a0e-cf94-487c-be83-a43b719d8c45 Error Number:-2,State:0,Class:11

System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding. ---> System.ComponentModel.Win32Exception: Der Wartevorgang wurde abgebrochen --- End of inner exception stack trace --- at System.Data.SqlClient.SqlCommand.<>c.b__107_0(Task`1 result) at System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke() at System.Threading.Tasks.Task.Execute() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.d__20.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable.AsyncEnumerator.d__8.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.SelectAsyncEnumerable`2.SelectAsyncEnumerator.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.SelectAsyncEnumerable`2.SelectAsyncEnumerator.d__4.MoveNext() --- End of stack trace from previous location where exception was thrown --- at System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(Task task) at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task) at Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.d__5.MoveNext() ClientConnectionId:64923a0e-cf94-487c-be83-a43b719d8c45 Error Number:-2,State:0,Class:11 Ausnahme ausgelöst: "System.Data.SqlClient.SqlException" in System.Private.CoreLib.ni.dll

但是,如果我改變LINQ的表達下面的循環,一切工作正常:

var orders = new List<ExampleClass>(); 
int number = 0; 

foreach (var data in DataRepo) 
{ 
    if (data.number == number) 
    { 
     orders.Add(data); 
    } 
} 

我還沒有見過有誰的Wi同樣的問題..

有沒有人知道爲什麼會這樣? 非常感謝

+0

第一個代碼導致服務器超時。您可能需要在表格中添加一些索引。 – FDB

回答

1

由於超時是由SQL客戶端報告的,我猜這不是Linq Expression的問題,而是與編譯的SQL語句對數據庫的執行。唯一的例外給出了兩個提示:

  • 的超時時間操作完成之前經過
  • 服務器沒有響應

Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory:Error: An exception occurred in the database while iterating the results of a query. System.Data.SqlClient.SqlException: Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.

關於你的第二個代碼加載整個表的事實在超時期限內進入內存,我們可以排除第二個選項。

The default timeout of the SQL Connection is 15 seconds.這應該適用於執行簡單的查詢,如您的代碼將生成的那樣。當整個表的加載大於由where子句中的單個參數過濾更快,則最有可能與分度一個問題:

  • 上「數字」
  • 索引缺少索引的碎片或其統計數據不起來做日期
  • 的指數是不恰當的,因爲數千行有「數」 = 0
  • 表的聚集索引是零散的
  • 其他原因

爲了將問題集中在數據庫中,我將提取SQL查詢 - 通過在調試器中跟蹤SQL字符串或使用SQL Server Profiler - 在SQL Server Management Studio中執行它並分析執行計劃以獲取更多信息。

要排除異步查詢執行的副作用,我還會在默認的同步上下文中進行一些測試。