【问题标题】:Entity Framework Query Timeout实体框架查询超时
【发布时间】:2014-10-29 20:00:47
【问题描述】:

在我的控制器中,我有以下代码:

    public ActionResult Syslogs(string IPAddress) {
        IEnumerable<Syslogd> syslogs = db.Syslogds.Take(100).ToList();

        if (!String.IsNullOrEmpty(IPAddress)) {
            syslogs = db.Syslogds.Where(s => s.MsgHostname == IPAddress).Take(100).ToList();
        }

        return View(syslogs.ToList());
    }

每当我将某个值传递给IPAddress 变量时,查询就会超时。我不确定为什么会发生这种情况或如何防止它。该值是否在数据库中不存在,或者只是需要很长时间才能找到它?这是我收到的错误消息:

类型异常 'System.Data.Entity.Core.EntityCommandExecutionException' 发生在 EntityFramework.SqlServer.dll 但未在用户代码中处理

附加信息:执行命令时出错 定义。有关详细信息,请参阅内部异常。

内部异常:

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

【问题讨论】:

  • 附带说明,即使您使用 IP 上的过滤器覆盖这些值,您也始终执行第一个查询。您应该将第一个查询移到 else 子句以避免做任何额外的不必要的工作。
  • Syslogd 有多少条记录?数据库是否在单独的机器上?什么是网络带宽使用率?

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


【解决方案1】:

该值可能不存在,但超时仅表示查询未在给定的命令执行时间内完成。我认为 EF 的默认超时时间是命令的 30 秒。

基本问题,但是,如果您的 Syslogd 表有很多记录,那么 MsgHostname 上是否有索引?

【讨论】:

  • 我发现数据库中不存在该记录。我想我现在的问题是如何在执行查询之前检查它?我已经尝试过 db.Syslogd.Any() 但这没有用。
【解决方案2】:

正如 Ryan 所说,EF 的默认超时时间是 commands 的 30 秒。所以你可以增加执行超时时间。

通过使用CommandTimeOut

// Specify a timeout for queries in this context, in seconds.
context.CommandTimeout = 120;  

Reference

也请考虑一下:

  1. 此外,您正在使用.ToList(),这是通过以下方式强制执行查询 立即,我认为您可以避免这种情况以提高性能。
  2. IEnumerable 适用于从内存集合中查询数据,如 List、Array 等,但不适合从内存外(如远程数据库、服务)集合和分页中查询数据。

所以我强烈建议在这种情况下使用IQueryable

参考
codeproject

IQueryable Vs. IEnumerable in terms of LINQ to SQL queries

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-08-15
    • 1970-01-01
    • 1970-01-01
    • 2011-09-08
    • 2015-01-27
    • 1970-01-01
    • 2021-12-25
    相关资源
    最近更新 更多