Linq Count() 超时 - 执行超时已过期。操作完成前超时时间已过或服务器无响应

Posted

技术标签:

【中文标题】Linq Count() 超时 - 执行超时已过期。操作完成前超时时间已过或服务器无响应【英文标题】:Linq Count() timing out -Execution Timeout Expired. The timeout period elapsed prior to completion of the operation or the server is not responding 【发布时间】: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 【参考方案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 的额外索引也不会受到影响。

【讨论】:

以上是关于Linq Count() 超时 - 执行超时已过期。操作完成前超时时间已过或服务器无响应的主要内容,如果未能解决你的问题,请参考以下文章

在 SQL Server 2008 中执行视图时出现“超时已过期”错误

执行 DbCommand 失败,因为超时已过期 .net 核心

SqlException:超时已过期

如何在 EF Core 3.1 中使用脚手架流程更新我的实体 - 执行超时已过期

如何解决超时过期问题?

sql 2000 超时已过期?怎么办!? 呼唤高手!