【问题标题】:Why does this LINQ statement throw a timeout error?为什么此 LINQ 语句会引发超时错误?
【发布时间】:2013-11-29 13:53:56
【问题描述】:

执行此行时出现此错误,通过断点检测到此错误。

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

int? dressSerialNo;
var lstDress = (
    from yy in currContext.OrderDressings
    where yy.OrderID == this.OrderID
        && yy.OrderItemID == this.orderItemID
        && yy.ProductID == this.ProductID
    select yy
    ).ToList();
if (lstDress.Count > 0)
{
    dressSerialNo = (
        from yy in lstDress
        where yy.OrderID == this.OrderID
            && yy.OrderItemID == this.orderItemID
            && yy.ProductID == this.ProductID
        select (int?)yy.SrNo
        ).Max();
    dressSerialNo += dressSerialNo + 1;
}
else dressSerialNo = 1;

解决方案:- 在我的项目中,我在两个使用 ado.net 的模块旧方法和新开发的模块中对事务进行主线处理,我使用的是实体框架,因此它在事务中产生了问题。所以它变得异常了。

【问题讨论】:

  • 始终使用seq.Any() 而不是seq.Count > 0。即使这里是一个列表,使用Any 更易读,如果您删除ToList 并改用seq.Count() > 0,效率也会更高。你想知道它是否包含任何元素,你不想知道总数。
  • 删除 .ToList() 看看会发生什么。
  • @TimSchmelter 对于访问Count 的列表很好
  • @TimSchmelter 这里Count 字段
  • 启动 SQL 分析器,捕获查询,在 SSMS 中运行并分析查询计划。除了明显的“试试这个”猜谜游戏之外,我们真的无话可说。

标签: c# linq


【解决方案1】:

您正在使用Linq-To-Entities。与数据库服务器的连接存在问题。造成这种情况的常见原因是:

  • 查询花费的时间超过了上下文中指定的超时时间。
  • 存在导致延迟的网络相关问题。

您可以选择更改命令超时(请参阅this question 了解如何执行此操作)。

【讨论】:

    【解决方案2】:

    您不想使用 .ToList() 实现所有实体。

    您可以编写一个查询,只返回您感兴趣的内容:

    // Get the entity that contains the max value, using Ordering
    var myMaxIfAny = currContext.OrderDressings
        .Where(yy => yy.OrderID == this.OrderID && yy.OrderItemID == this.orderItemID && yy.ProductID == this.ProductID)
        .OrderByDescending(z => z.SrNo)
        .FirstOrDefault();
    
    if (myMaxIfAny != null)
    {
        // Then you got a value, retrieve the Max using myMaxIfAny.SrNo
        // ...
    }
    else
    {
        // ...
    }
    

    【讨论】:

      【解决方案3】:

      我已经对您的代码进行了格式化和注释:

      int? dressSerialNo;
      
      // Get all OrderDressings with matching OrderID, orderItemID and ProductID as a List<OrderDressing>
      var lstDress = (from yy in currContext.OrderDressings 
                      where yy.OrderID == this.OrderID 
                         && yy.OrderItemID == this.orderItemID 
                         && yy.ProductID == this.ProductID 
                      select yy)
                      .ToList();
      
                      // If any were found,               
                      if (lstDress.Count > 0)
                      {
                          // Execute the Where again (what else will the list contain?) and select all yy.SrNo
                          dressSerialNo = (from yy in lstDress 
                                           where yy.OrderID == this.OrderID 
                                              && yy.OrderItemID == this.orderItemID 
                                              && yy.ProductID == this.ProductID 
                                          select (int?)yy.SrNo)
                                          .Max();     // And take the Max() of that
      
                          // Add dressSerialNo + 1 to dressSerialNo.
                          dressSerialNo += dressSerialNo + 1;
                      }
      
                      else dressSerialNo = 1;
      

      这似乎可以纠正并简化为:

      int? serialNumber = (from yy in currContext.OrderDressings 
                           where yy.OrderID == this.OrderID 
                              && yy.OrderItemID == this.orderItemID 
                              && yy.ProductID == this.ProductID 
                           select yy.SrNo)
                           .DefaultIfEmpty() // Might not be necessary
                           .Max();
      
      if (!serialNumber.HasValue)
      {
          serialNumber = 1;
      }
      else
      {
          serialNumber++;
      }
      

      请注意,如果两个人同时执行此操作,这可能会导致并发问题。

      【讨论】:

      【解决方案4】:

      对数据库的查询耗时过长。为什么会发生这种情况有很多原因。

      尝试将linq生成的sql语句直接运行到数据库中,看看是否耗时。

      检查并查看您的任何列是否包含大量数据。 (就像一个充满大量数据的字符串列)

      同时尝试将其添加到连接字符串的末尾

      Connection Timeout=30000;

      【讨论】:

        【解决方案5】:

        我发现了它造成超时问题的问题, 在我的应用程序中,事务以 2 种风格维护, 一个是旧的 ado.net 风格,另一个是 EF 风格, 所以造成了混乱。我要把它统一起来,以改变实体框架。

        【讨论】:

          猜你喜欢
          • 2021-11-14
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2020-03-25
          • 1970-01-01
          • 1970-01-01
          • 2014-12-11
          相关资源
          最近更新 更多