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
This is how I do it.
ObjectContext objectContext = ((IObjectContextAdapter)dbContext).ObjectContext
int commandTimeout = objectContext.CommandTimeout
?? objectContext.Connection.CreateCommand().CommandTimeout;
This should work
var ctx = new DbContext();
ctx.Database.CommandTimeout = 120;
From MSDN,
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,
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.
- 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.
- 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
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;
If you're using SQLServer then the default command timeout is 30 seconds.
SqlCommand.CommandTimeout Property