【问题标题】:LINQ-Expression fails but foreach loop works Entity-FrameworkLINQ-Expression 失败,但 foreach 循环有效
【发布时间】:2017-09-01 13:12:54
【问题描述】:

我的应用程序是 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:迭代查询结果时数据库中发生异常。 System.Data.SqlClient.SqlException:超时已过期。在操作完成之前超时时间已过或服务器没有响应。 ---> System.ComponentModel.Win32Exception: Der Wartevorgang wurde abgebrochen --- 内部异常堆栈跟踪结束 --- 在 System.Data.SqlClient.SqlCommand.c.b__107_0(任务`1 结果) 在 System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke() 在 System.Threading.Tasks.Task.Execute() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.d__20.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable.AsyncEnumerator.d__8.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.SelectAsyncEnumerable`2.SelectAsyncEnumerator.d__4.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.SelectAsyncEnumerable`2.SelectAsyncEnumerator.d__4.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.d__5.MoveNext() ClientConnectionId:64923a0e-cf94-487c-be83-a43b719d8c45 错误号:-2,状态:0,类:11

System.Data.SqlClient.SqlException:超时已过期。在操作完成之前超时时间已过或服务器没有响应。 ---> System.ComponentModel.Win32Exception: Der Wartevorgang wurde abgebrochen --- 内部异常堆栈跟踪结束 --- 在 System.Data.SqlClient.SqlCommand.c.b__107_0(任务`1 结果) 在 System.Threading.Tasks.ContinuationResultTaskFromResultTask`2.InnerInvoke() 在 System.Threading.Tasks.Task.Execute() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Storage.Internal.RelationalCommand.d__20.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Query.Internal.AsyncQueryingEnumerable.AsyncEnumerator.d__8.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.SelectAsyncEnumerable`2.SelectAsyncEnumerator.d__4.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.SelectAsyncEnumerable`2.SelectAsyncEnumerator.d__4.MoveNext() --- 从先前抛出异常的位置结束堆栈跟踪 --- 在 System.Runtime.CompilerServices.TaskAwaiter.ThrowForNonSuccess(任务任务) 在 System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(任务任务) 在 Microsoft.EntityFrameworkCore.Query.Internal.AsyncLinqOperatorProvider.ExceptionInterceptor`1.EnumeratorExceptionInterceptor.d__5.MoveNext() ClientConnectionId:64923a0e-cf94-487c-be83-a43b719d8c45 错误号:-2,状态:0,类:11 Ausnahme ausgelöst:System.Private.CoreLib.ni.dll 中的“System.Data.SqlClient.SqlException”

但是,如果我将 LINQ 表达式更改为以下循环,一切正常:

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

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

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

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

【问题讨论】:

  • 第一个代码导致服务器超时。您可能需要在表格上添加一些索引。

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


【解决方案1】:

由于 SQL 客户端报告了超时,我猜这不是 Linq 表达式的问题,而是针对数据库执行已编译的 SQL 语句的问题。该异常给出了两个提示:

  • 在操作完成之前超时时间已过
  • 服务器没有响应

Microsoft.EntityFrameworkCore.Query.Internal.SqlServerQueryCompilationContextFactory:Error:迭代查询结果时数据库中发生异常。 System.Data.SqlClient.SqlException:超时已过期。在操作完成之前超时时间已过或服务器没有响应。

关于您的第二个代码在超时时间内将整个表加载到内存中的事实,我们可以排除第二个选项。

The default timeout of the SQL Connection is 15 seconds. 这应该适合执行简单的查询,例如您的代码将生成的查询。当加载整个表比通过 where 子句中的单个参数过滤它更快时,很可能存在索引问题:

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

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

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

【讨论】:

    猜你喜欢
    • 2021-08-15
    • 1970-01-01
    • 2018-03-13
    • 1970-01-01
    • 2021-04-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-08
    相关资源
    最近更新 更多