35

I'm using Entity Framework 5 and I wish to know the command timeout value.

In order to do so, I cast the dbContext object to an ObjectContext and I access the CommandTimeout property.

int ? currentCommandTimeout = ((IObjectContextAdapter)dbContext).ObjectContext.CommandTimeout;

The current value of this property is null which means that the current command timeout is the default value of the underlying provider.

  1. Who is the underlying provider?
  2. How can I read (via EF code) the current command timeout value in this case?

MSDN ObjectContext CommandTimeout Property reference

EDIT: Thank you for explaining how to set the command timeout and finding the default command timeout value in the documentation. However, the question remains open. How, if possible, can you read the command timeout value in case of default, via EF.

RBT
  • 24,161
  • 21
  • 159
  • 240
Oren
  • 2,462
  • 3
  • 18
  • 16
  • are u passing it in connectionString? – Bhushan Firake Jun 11 '13 at 16:28
  • No. I have not set it myself in any way. I just wish to know the current value of the command timeout (which is probably a default). – Oren Jun 11 '13 at 16:31
  • Which database are you using? – Bhushan Firake Jun 11 '13 at 16:33
  • possible duplicate of http://stackoverflow.com/questions/6232633/entity-framework-timeouts – gunr2171 Jun 11 '13 at 16:57
  • @gunr2171 - The question you linked is about how to set the timeout value. My question is about how to read that value when it is default value of the underlying provider. – Oren Jun 11 '13 at 17:56
  • I doubt there is a way as it depends on the underlying provider which can be SQL Server, MySql, Oracle etc. EF can only pass a new value to the underlying provider on your behalf if you mention an explicit value in the connection string. More details here - http://stackoverflow.com/questions/13647493/default-entity-framework-timeout – RBT Aug 20 '16 at 06:45

5 Answers5

27

From MSDN,

  • CommandTimeout property gets or sets the timeout value, in seconds, for all object context operations.
  • A null value indicates that the default value of the underlying provider will be used.

So, if you are not setting it explicitly through code or passing it in your connection string (in MySQL) , then it is the default value of your provider.

If you want to see a non-null value for CommandTimeout, then you will need to pass it in connectionString or set it through code.

Who is the underlying provider?

Underlying provider is the one you are passing in your connectionstring as providerName

<connectionStrings>
  <clear />
  <add name="Name" 
   providerName="System.Data.ProviderName" 
   connectionString="Valid Connection String;" />
</connectionStrings>

Here, System.Data.ProviderName is your underlying provider.

If you are using MySql or MS Sql, According to the MySql Documentation and MSDN,

  • The default value is 30 secs.
  • A value of 0 indicates an indefinite wait and should be avoided.

    Note :

The default command timeout can be changed using the connectionstring attribute Default Command Timeout in case of MySQL database providers.

RBT
  • 24,161
  • 21
  • 159
  • 240
Bhushan Firake
  • 9,338
  • 5
  • 44
  • 79
  • 3
    -1 That is exactly what OP wrote in question (he even provided a link). And it does not answer who is underlying provider, and how get current timeout value – Sergey Berezovskiy Jun 11 '13 at 16:43
  • 2
    Thank you Bhushan. However, this still does not answer my question. How can I read the value via code? – Oren Jun 12 '13 at 07:04
  • 3
    I disagree with this - `If you want to see a value for CommandTimeout, then you will need to pass it in connectionString.` **What you provide in connection string is connection timeout and NOT command timeout.** Connection timeout and command timeout are different things. **Command timeout can never be set through connection string**. There is no such property which can be set in connection string formats supported by SQL Server. see [here](http://www.connectionstrings.com/all-sql-server-connection-string-keywords/). Command timeout can be set only through the command object in your C# code. – RBT Aug 20 '16 at 07:16
  • @RBT Whatever note I have written is for Mysql. You can find the official statement here:https://dev.mysql.com/doc/connector-net/en/connector-net-programming-mysqlcommand.html. If you think, my note isn't clear about a particular db . you are free to update it. – Bhushan Firake Aug 20 '16 at 07:31
  • 1
    @BhushanFirake you were right. MySql database connection strings indeed have a support for mentioning command timeouts. I've elaborated the things from both SQL Server and mySql database stand-point. Actually I read the question and your answer both from EF interacting with SQL Server stand point when the question is very generic where the EF could be interacting with any database provider. I had made a one liner change in your post also to make it more clear from mySQL database stand-point. – RBT May 29 '17 at 23:45
6

If you're using SQLServer then the default command timeout is 30 seconds.

SqlCommand.CommandTimeout Property

Jason Massey
  • 1,088
  • 10
  • 18
  • 4
    Thanks Jason. I understand that the default value should be 30. However, the question remains. How can I read this value via Entity Framework 5 code when it is in default. – Oren Jun 11 '13 at 18:08
5

This should work

var ctx = new DbContext();
ctx.Database.CommandTimeout = 120;
afr0
  • 848
  • 1
  • 11
  • 29
5
  1. Who is the underlying provider?

For connecting to any database remotely and firing SQL queries you need a mechanism or a mediator (you can say) which understands the communication semantics of various actions to be taken while firing a query e.g. creating command, making connection, taking care of connection timeout, retry etc.

All these responsibilities are taken care of by providers for the database you are trying to connect to. These providers will have different implementations and classes w.r.t. the environment (C#, Java, Python,Perl etc) you are connecting from. So to connect to a MySQL database you will have different providers for java, .net, or python programming world.

  1. How can I read (via EF code) the current command timeout value in this case?

Nope. This is not possible. If you closely look at the dbContext.Database.CommandTimeout property, it is of type int?. So the logistics of keeping this property as nullable int is only to represent the default value (as null). Entity Framework (EF) doesn’t expose anything until you have set an explicit value in C# code. I verified this against following databases

  • MySQL
  • SQL Server

In both the cases I see that after creating the DB context object the command time out property is set to null which suggests that it is using the default provided by the underlying provider.

But yes, if you have set it to a non-null value once in your C# code through dbContext.Database.CommandTimeout property, then you can of course read it again as it is a get-set property on the command object. It will always show you the new value which was set explicitly in code.

If you set it back to null then EF will again start using the default timeout of the underlying provider.

Using Provider Classes in place of EF layer: If you don’t use the ORM layer of entity framework and use the core classes of the provider instead then you can certainly see the default timeout value on initialization itself. Like when I ran below mentioned code for a MySQL database with default command time out value already set in the connection string itself then you get to see 40.

private static void TestingCommandTimeOutInMySql()
        {
            string connetionString = "Server=localhost;Database=sakila;Uid=root;Pwd=Passw0rd;default command timeout=40;";
            MySqlConnection con = new MySqlConnection(connetionString);
            try
            {
                cnn.Open();
                Console.WriteLine("Connection Open ! ");
                MySqlCommand cmd = new MySqlCommand("select * from actor", con);
                var timeoutValue = cmd.CommandTimeout; //shows 40
                con.Close();
            }
            catch (Exception ex)
            {
                Console.WriteLine("Can not open connection ! ");
            }
        }

If you don’t set anything in the connection string it shows default value of 30 for MySQL. Here the CommandTimeout is int, NOT int?. So EF certainly does apply some intelligence while exposing this property of provider classes which are ultimately exposed by EF through dbContext.Database.CommandTimeout. EF is just a wrapper over these provider classes with some additional intelligence.

Few additional details regarding connection stings :

For SQL Server Provider: Microsoft SQL server connection string formats do not provide any property with the help of which you can set a custom command execution timeout. So setting a value during the initialization of the SQL Server provider is simply not possible. You can always change the value in C# code though after the intantiation/initialization. You can see more details here.

For MySQL Provider: My SQL connection string formats have a support for setting the default command timeout explicitly. You can find the details here. You can mention a custom default command timeout value in the MySQL connection string like this -

default command timeout=200;
RBT
  • 24,161
  • 21
  • 159
  • 240
  • Just out of curiousity, could you point out the spot in the [EF Core SQL Server Provider GitHub repository](https://github.com/dotnet/efcore) where this default timeout of 30 s is set? – Matthias Schuchardt Dec 07 '20 at 13:29
2

This is how I do it.

ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext
int commandTimeout = objectContext.CommandTimeout 
    ?? objectContext.Connection.CreateCommand().CommandTimeout;
enoshixi
  • 309
  • 3
  • 13
  • 4
    That's a bit overdone. It's as simple as `int commandTimeout = dbContext.Database.CommandTimeout`. – Gert Arnold Jul 28 '16 at 20:22
  • wow, this is really nice, I believe this is the exact answer. EF Core counterpart is `dbContext.Database.GetDbConnection().CreateCommand().CommandTimeout` . Using this I can get aforementioned default SqlServer commandtimeout value which is 30. Just no need to read docs now :) – mkb Aug 06 '20 at 20:50