c# - LINQ 表达式失败,但 foreach 循环有效 Entity-Framework

标签 c# entity-framework linq asp.net-core sqlexception

我的应用程序是 ASP.NET Core 1.0 Web API。

我的代码中有以下 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);
   }
}

我还没见过有同样问题的人..

有谁知道为什么会这样吗? 非常感谢

最佳答案

由于 SQL 客户端报告了超时,我猜测这不是 Linq 表达式的问题,而是针对数据库执行已编译的 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 子句中的单个参数过滤它更快时,很可能存在索引问题:

  • 缺少“number”索引
  • 索引高度分散或其统计信息不是最新的
  • 索引不合适,因为数千行的 'number' = 0
  • 表的聚集索引碎片
  • 其他原因

为了将问题集中在数据库中,我将提取 SQL 查询 - 通过在调试器中跟踪 SQL 字符串或使用 SQL Server Profiler - 在 SQL Server Management Studio 中执行它并分析执行计划以获取更多信息.

为了排除异步查询执行的副作用,我还会在默认同步上下文中进行一些测试。

关于c# - LINQ 表达式失败,但 foreach 循环有效 Entity-Framework,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43256307/

相关文章:

c# - 如何找到 Windows Phone 8.1 Xaml 应用程序内存泄漏的原因?

c# - 跨多个上下文共享 EF 中的连接和事务(UnintentionalCodeFirstException)

c# - 如何在 LINQ 查询语言的 Where 中使用索引/位置?

c# - Linq 和 SQL 之间的不同结果

c# - 如何指定用于 WebClient 类的 SSL 协议(protocol)

c# - "System.Net.Sockets.Socket does not contain a definition for ' 发送至 '"

c# - 序列化组装。需要还是不需要?

nhibernate - 存储库/工作单元模式 - 如何在存储库中查询满足特定条件的对象?

entity-framework - 只获取特定的列

c# - 将 Web 服务中的数据表写入 XML 的最佳方式?