0

In my controller I have the following code:

    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());
    }

The query times out whenever I pass a certain value to the IPAddress variable. I'm not sure why that is happening or how I can prevent it. Does the value not exist in the database or is it just taking a long time to find it? Here is the error message I receive:

An exception of type 'System.Data.Entity.Core.EntityCommandExecutionException' occurred in EntityFramework.SqlServer.dll but was not handled in user code

Additional information: An error occurred while executing the command definition. See the inner exception for details.

The inner exception:

{"Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding."}

mdk09
  • 287
  • 1
  • 4
  • 17
  • 1
    On a side note, you are always executing the first query even if you are overwriting those values with a filter on IP. You should move the first query to the else clause to avoid doing any extra unnecessary work. – Wouter de Kort Oct 29 '14 at 20:05
  • How many records does Syslogd have? Is the database on a separate machine? What is network bandwidth usage? – Louis Michael Oct 29 '14 at 22:02

2 Answers2

3

It's possible that the value doesn't exist, but a Timeout just means that the query didn't complete in the time given for the command to execute. I think the default timeout for EF is 30 seconds for commands.

Basic question, but, if your Syslogd table has many records, is there an index on MsgHostname?

Ryan Nigro
  • 4,389
  • 2
  • 17
  • 23
  • I have discovered that the record just doesn't exist in the database. I guess my question now is how can I check for that before executing the query? I have tried db.Syslogd.Any() but that didn't work. – mdk09 Oct 30 '14 at 16:19
1

As Ryan said default timeout for EF is 30 seconds for commands . So you can increase the execution timeout time.

By using CommandTimeOut:

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

Reference

Or by using Database.CommandTimeout

// or for all object in context (in seconds)
context.Database.CommandTimeout = 120;

Consider this also:

  1. Moreover you are using .ToList() which is forcing immediate query execution and I think you can avoid that to improve the performance.
  2. IEnumerable is suitable for querying data from in-memory collections like List, Array etc, but it's not suitable for querying data from out-memory (like remote database, service) collections and paging.

So I strongly recommend to use IQueryable in this case.

Reference
codeproject

IQueryable Vs. IEnumerable in terms of LINQ to SQL queries

David Fox
  • 10,603
  • 9
  • 50
  • 80
ManirajSS
  • 2,295
  • 5
  • 26
  • 50