【问题标题】:Linq Count() timing out -Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not respondingLinq Count() 超时 - 执行超时已过期。操作完成前超时时间已过或服务器无响应
【发布时间】:2021-12-03 02:07:09
【问题描述】:

我有一个 linq 查询,它试图从数据库中获取大约 500K 记录。 我有一个 Count() 最终超时。

我想知道我的 linq 查询是否包含 5000 条或更多记录。我没有统计所有记录,只需要检查 linq 是否包含 5000 条记录。

有没有什么有效的方法可以在不调用 Count() 的情况下检查 linq 中是否有 5000 条或更多记录?我正在使用 EF 核心 3.1。

Linq 查询:

  var results = (from a in RepoContext.Employee
                          join b in RepoContext.Program on a.ProgramId equals b.ProgramId 
                          where a.ActiveFlag == true
                                && b.ClientId == 2
                          select new RAManufacturerDto
                          {

                              BusinessName = a.BusinessName,
                              ClientId = a.ClientId.Value,
                              ClientName = b.ClientName
                              DCode = b.DCode,
                              StoreId = b.StoreId,
                              ProgramId = a.ProgramId
                          });

bool isRecordsLimitReached = results.Count() > 5000;

尝试对结果执行 Count() 时出现错误。我只想知道它是否包含超过 5000 条记录。

【问题讨论】:

  • 如果您能提供一些上下文,这将是一个更好的问题。你能给我们看一些代码吗?
  • @sachin 请给我们看代码,没有看到是不可能的
  • @RobertHarvey 我编辑了我的问题。
  • @viveknuna 我编辑了我的问题。
  • 如果您只需要计数,请不要选择列,只需执行Count。您还可以在Count 中添加条件来代替Where

标签: c# .net sql-server entity-framework-core-3.1


【解决方案1】:

直接使用 linq,假设您正确配置了 dbcontext,并且在 onmodelcreating 中定义了两者之间的这种关系,请将代码移动到 RepoContext。 (如果对定义关系有疑问,请查看:https://docs.microsoft.com/en-us/ef/core/modeling/relationships?tabs=fluent-api%2Cfluent-api-simple-key%2Csimple-key

    DbSet<Employee> Employees {get;set;}
    DbSet<Program> Programs {get;set;}

    public bool HasMoreThan(int number) {
      var count = RepoContext.Employee.Include(x => x.Program).Count(y => 
      y.ActiveFlag == true && y.Program.ClientId == 2);
      return count >= number;
    }

【讨论】:

    【解决方案2】:

    尝试跳过 5000 条记录,如果有记录 - 我们已经达到目标:

    bool isRecordsLimitReached = results.Skip(5000).Any();
    

    【讨论】:

      【解决方案3】:

      如果您只需要获取计数,则无需选择所有这些属性。您可以通过仅选择一个不可为空的属性来优化此查询。

      var results = (from a in RepoContext.Employee
                     join b in RepoContext.Program on a.ProgramId equals b.ProgramId 
                     where a.ActiveFlag == true && 
                     b.ClientId == 2
                     select a.Id); //Id = Primary Key of the Employee database
      
      bool isRecordsLimitReached = results.Count() > 5000;
      

      如果您仍然遇到超时,那么您可能需要在 Program 表上的外键中添加一个索引(如果它不存在的话)。 ActiveFlag 和 ClientId 的额外索引也不会受到影响。

      【讨论】:

        猜你喜欢
        • 2012-05-01
        • 2012-07-24
        相关资源
        最近更新 更多