181

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
    – itsho
    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.
    – Worthy7
    Commented Aug 18, 2017 at 6:18

11 Answers 11

220

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

10
  • 1
    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. Commented Mar 5, 2013 at 18:24
  • 144
    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). Commented Jul 25, 2013 at 11:01
  • 3
    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/…
    – Karsten
    Commented Aug 14, 2014 at 7:42
  • 2
    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.
    – Jim Aho
    Commented Oct 9, 2014 at 8:22
  • 1
    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
    – Jezbers
    Commented Jul 17, 2015 at 15:34
201

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

It's pretty simple and no cast required.

1
  • 2
    Very useful for us that use Fluent API form of EF.
    – GoldBishop
    Commented May 18, 2016 at 16:51
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.

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;
    }
}
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));
    } 
}
0
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
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
  • and how do i call this extension method? Commented Feb 16, 2018 at 21:39
1

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

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
  • connection timeout != command timeout! Commented Nov 18, 2022 at 12:18
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);
      }
-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
  • 1
    As noted earlier: connection timeout != command timeout. Command timeout is what matters here. Commented Apr 2, 2021 at 8:54
  • This approach was to read it dynamically from the Connection String rather than making a separate setting for it. Commented Apr 7, 2021 at 8:10
  • That detail escaped my eye, and that immediately shows the problem with such hacks. It's totally unexpected and should never be done. Commented Apr 7, 2021 at 8:18
  • 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. Commented Apr 14, 2021 at 10:51
  • 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. Commented Apr 14, 2021 at 11:54

Not the answer you're looking for? Browse other questions tagged or ask your own question.