以下是我在使用 EDMX 文件时解决此问题的方法。该解决方案更改了默认的 T4 模板,使生成的类继承自自定义 DbContext 类,该类指定了默认的命令超时,以及用于更改它的属性。
我正在使用 Visual Studio 2012 和 EF 5.0。您的体验可能与其他版本不同。
创建自定义 DbContext 类
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;
}
}
}
这有一个可选功能:我没有硬编码默认命令超时。相反,我从项目设置中加载它,以便我可以更改配置文件中的值。如何设置和使用项目设置不在此答案的范围内。
我也没有硬编码连接字符串或连接字符串名称。它已经由生成的上下文类传递给构造函数,因此在这里对其进行硬编码是没有意义的。这不是什么新鲜事。 EDMX 文件已经为您生成了以下构造函数,所以我们只是传递值。
public MyEntities()
: base("name=MyEntities")
{
}
(这指示 EF 从配置文件中加载名为“MyEntities”的连接字符串。)
如果ObjectContext 为空,我将抛出自定义异常。我认为它永远不会,但它比获得NullReferenceException 更有意义。
我将ObjectContext 存储在一个字段中,以便我可以创建一个属性来访问它以覆盖默认值。
修改实体上下文 T4 模板
在解决方案资源管理器中,展开 EDMX 文件以查看 T4 模板。他们有一个 .tt 扩展名。
双击“MyModel.Context.tt”文件将其打开。在第 57 行附近,您应该会看到:
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
此模板行生成“MyEntities”类的类定义,该类继承 DbContext。
改行,让生成的类继承CustomDbContext,改为:
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : CustomDbContext
一旦你保存了这个文件,它就会重新生成这个类。如果没有,您可以右键单击 EDMX 文件并选择“运行自定义工具”。如果您在 EDMX 文件下展开“MyModel.Context.tt”文件,您将看到“MyModel.Context.cs”。这就是生成的文件。打开它,你应该会看到它现在继承了CustomDbContext。
public partial class MyEntities : CustomDbContext
仅此而已。
问题
一旦将上下文类从 DbContext 更改为 CustomDbContext,如果您尝试使用“具有读/写操作和视图的控制器,使用 Entity Framework “ 模板。它会说“不支持的上下文类型。”。要解决此问题,请打开生成的“MyModel.Context.cs”类,并将其继承的类型临时更改回DbContext。添加新控制器后,您可以将其改回CustomDbContext。