Here's how I solved this problem when using an EDMX file. This solution changes the default T4 template to make the generated class inherit from a custom DbContext class, which specifies a default command timeout, and a property to change it.
I'm using Visual Studio 2012 and EF 5.0. Your experience may differ with other versions.
Create a custom DbContext class
public class CustomDbContext : DbContext
{
ObjectContext _objectContext;
public CustomDbContext( string nameOrConnectionString )
: base( nameOrConnectionString )
{
var adapter = (( IObjectContextAdapter) this);
_objectContext = adapter.ObjectContext;
if ( _objectContext == null )
{
throw new Exception( "ObjectContext is null." );
}
_objectContext.CommandTimeout = Settings.Default.DefaultCommandTimeoutSeconds;
}
public int? CommandTimeout
{
get
{
return _objectContext.CommandTimeout;
}
set
{
_objectContext.CommandTimeout = value;
}
}
}
This has an optional feature: I'm not hard-coding the default command timeout. Instead, I'm loading it from the project settings so that I can change the value in a config file. How to setup and use project settings is not in the scope of this answer.
I'm also not hard-coding the connection string or connection string name. It's already passed into the constructor by the generated context class, so it makes no sense to hard-code it here. This is nothing new; the EDMX file already generates the following constructor for you, so we are just passing along the value.
public MyEntities()
: base("name=MyEntities")
{
}
(This instructs EF to load the connection string named "MyEntities" from the config file.)
I'm throwing a custom exception if the ObjectContext
is ever null. I don't think it ever will be, but it's more meaningful than getting a NullReferenceException
.
I store the ObjectContext
in a field so that I can make a property to access it to override the default.
Modifying the entity context T4 template
In the Solution Explorer, expand the EDMX file so that you see the T4 templates. They have a .tt extension.
Double click the "MyModel.Context.tt" file to open it. Around line 57 you should see this:
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
This template line generates the class definition of your "MyEntities" class, which inherits DbContext.
Change the line so that the generated class inherits CustomDbContext, instead:
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : CustomDbContext
As soon as you save this file it should regenerate the class. If not, you can right-click the EDMX file and select "Run Custom Tool". If you expand the "MyModel.Context.tt" file under your EDMX file, you will see "MyModel.Context.cs". That's the generated file. Open it, and you should see that it now inherits CustomDbContext
.
public partial class MyEntities : CustomDbContext
That's all there is to it.
Issues
Once you change the context class from DbContext
to CustomDbContext
, Visual Studio will give you an error if you try to add a new MVC controller class using the "Controller with read/write actions and views, using Entity Framework" template. It will say "Unsupported context type.". To get around this, open the generated "MyModel.Context.cs" class, and temporarily change the type it inherits back to DbContext
. After adding your new controller, you can change it back to CustomDbContext
.