183

My command keeps timing out, so I need to change the default command timeout value.

I've found myDb.Database.Connection.ConnectionTimeout, but it's readonly.

How can I set the command timeout in Entity Framework 5 ?

4
  • 20
    FYI, On EF6, Database.CommandTimeout is no longer read-only Commented Jun 25, 2014 at 21:33
  • 2
    @itsho He was talking about Database.Connection.ConnectionTimeout. Anyway, I would say that Database.CommandTimeout is the right thing in the case your query is time-outing (exception System.Data.Entity.Core.EntityCommandExecutionException containing System.Data.SqlClient.SqlException: Timeout expired.). Commented Mar 4, 2016 at 14:59
  • 3
    Possible duplicate of Entity Framework Timeouts Commented Dec 1, 2016 at 10:05
  • 2
    I assume you actually don't care about the CONNECTION timeout, but instead you want to adjust the COMMAND timeout. Commented Aug 18, 2017 at 6:18

11 Answers 11

221

Try this on your context:

public class MyDatabase : DbContext
{
    public MyDatabase ()
        : base(ContextHelper.CreateConnection("Connection string"), true)
    {
        ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 180; // seconds
    }
}

If you want to define the timeout in the connection string, use the Connection Timeout parameter like in the following connection string:

<connectionStrings>

<add name="AdventureWorksEntities"
connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl;
provider=System.Data.SqlClient;provider connection string='Data Source=localhost;
Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60;
multipleactiveresultsets=true'" providerName="System.Data.EntityClient" />

</connectionStrings>

Source: How to: Define the Connection String

Sign up to request clarification or add additional context in comments.

10 Comments

I would recommend using the connection string version as if you try to access the ObjectContext in this constructor sometimes the PowerShell/NuGet console commands will fail in a circular way.
Connection Timeout and CommandTimeout and two separate things. The connection string setting, Connection Timeout, won't affect the amount of time the command runs (CommandTimeout).
My problem was a litte different. I got timeout during migrations. EF has a similar property to set for using during migrations: msdn.microsoft.com/en-us/library/…
Depending on what version of EF you use, see this answer to get a feeling about the different API's in how to specify the CommandTimeout property.
Does not work for me (Connection vs Command not being teh same thing I suspect). This post solved it though stackoverflow.com/questions/6232633/entity-framework-timeouts
|
203

You can use DbContext.Database.CommandTimeout = 180; // seconds

It's pretty simple and no cast required.

2 Comments

Very useful for us that use Fluent API form of EF.
ASP.Net Core/.NET 5++ syntax: ctx.Database.SetCommandTimeout(300);
21

My partial context looks like:

public partial class MyContext : DbContext
{
    public MyContext (string ConnectionString)
        : base(ConnectionString)
    {
        this.SetCommandTimeOut(300);
    }

    public void SetCommandTimeOut(int Timeout)
    {
        var objectContext = (this as IObjectContextAdapter).ObjectContext;
        objectContext.CommandTimeout = Timeout;
    }
}

I left SetCommandTimeOut public so only the routines I need to take a long time (more than 5 minutes) I modify instead of a global timeout.

Comments

10

In the generated constructor code it should call OnContextCreated()

I added this partial class to solve the problem:

partial class MyContext: ObjectContext
{
    partial void OnContextCreated()
    {
        this.CommandTimeout = 300;
    }
}

Comments

9

I extended Ronnie's answer with a fluent implementation so you can use it like so:

dm.Context.SetCommandTimeout(120).Database.SqlQuery...

public static class EF
{
    public static DbContext SetCommandTimeout(this DbContext db, TimeSpan? timeout)
    {
        ((IObjectContextAdapter)db).ObjectContext.CommandTimeout = timeout.HasValue ? (int?) timeout.Value.TotalSeconds : null;

        return db;
    }

    public static DbContext SetCommandTimeout(this DbContext db, int seconds)
    {
        return db.SetCommandTimeout(TimeSpan.FromSeconds(seconds));
    } 
}

Comments

9

For Database first Aproach:

We can still set it in a constructor, by override the ContextName.Context.tt T4 Template this way:

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
    public <#=code.Escape(container)#>()
        : base("name=<#=container.Name#>")
    {
        Database.CommandTimeout = 180;
<#
if (!loader.IsLazyLoadingEnabled(container))
{
#>
        this.Configuration.LazyLoadingEnabled = false;
<#
}

Database.CommandTimeout = 180; is the acutaly change.

The generated output is this:

public ContextName() : base("name=ContextName")
{
    Database.CommandTimeout = 180;
}

If you change your Database Model, this template stays, but the actualy class will be updated.

2 Comments

Is there way we can specify timeout in Template using some config file.?
not sure, if there something build in (I wasn't able to find something). But instead of hardcoding 180, you can use System.Configuration.ConfigurationManager.AppSettings["keyname"] @shas
8

Same as other answers, but as an extension method:

static class Extensions
{
    public static void SetCommandTimeout(this IObjectContextAdapter db, TimeSpan? timeout)
    {
        db.ObjectContext.CommandTimeout = timeout.HasValue ? (int?) timeout.Value.TotalSeconds : null;
    }
}

1 Comment

and how do i call this extension method?
1

You can use this simple :
dbContext.Database.SetCommandTimeout(300);

Comments

1

I just ran in to this problem and resolved it by updating my application configuration file. For the connection in question, specify "Connection Timeout=60" (I am using entity framework version 5.0.0.0)

ConnectionTimeout Setting

1 Comment

connection timeout != command timeout!
0

In my case the Connection string property is readonly. Also, the entities constructor is autogenerated so I didn't want to put it in there. Plus, putting in the constructor applied to all and I only needed it on one sproc.

Below is my workaround

try
     { using (MyEntities Mydb = new MyEntities())
       {
         (Mydb as System.Data.Entity.Infrastructure.IObjectContextAdapter).ObjectContext.CommandTimeout = 600;
         Mydb.LongRunningSproc();
        }
      }
  catch (System.Data.Common.DbException ex)
      {
          throw new Exception(SomeMessageHere);
      }

Comments

-2

You should make the changes in the Connection String tag in the web config and make the EntityFrameWork read from it in its contructor.

  1. Add this term to the web.config Connection String: Connection Timeout=300;

  2. Add the following code in the constructor:

    Database.CommandTimeout = Database.Connection.ConnectionTimeout;

By this approach you will make the user able to control the time out without make a new publish for him.

5 Comments

As noted earlier: connection timeout != command timeout. Command timeout is what matters here.
This approach was to read it dynamically from the Connection String rather than making a separate setting for it.
That detail escaped my eye, and that immediately shows the problem with such hacks. It's totally unexpected and should never be done.
The hacking checks should be done from other places and I thing the command time out of the command should be long enough to execute long queries or SQL commands. So the admin of the website should be able to control this period according to his needs without getting a new publish for just changing the command time out period.
NOT by abusing the Connection Timeout setting in the connection string! The next application manager will set it to some other value, unaware of its implications. And, remember, it also sets the connection timeout (obviously). You don't want people to wait for 5 minutes if the connection happens to be unavailable due to some contingency.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.