我想找到一种设置DbContext CommandTimeout的方法。搜索后,我发现可以将DbContext转换为ObjectContext,并为objectContext的CommandTimeout属性设置值。
var objectContext = (this.DbContext as IObjectContextAdapter).ObjectContext;
但是我必须使用DbContext。
我想找到一种设置DbContext CommandTimeout的方法。搜索后,我发现可以将DbContext转换为ObjectContext,并为objectContext的CommandTimeout属性设置值。
var objectContext = (this.DbContext as IObjectContextAdapter).ObjectContext;
但是我必须使用DbContext。
你的方法可以起作用。
或者从msdn论坛中继承它。
public class YourContext : DbContext
{
public YourContext()
: base("YourConnectionString")
{
// Get the ObjectContext related to this DbContext
var objectContext = (this as IObjectContextAdapter).ObjectContext;
// Sets the command timeout for all the commands
objectContext.CommandTimeout = 120;
}
}
as
的目的是什么?这样不会把“InvalidCastException”变成“NullReferenceException”吗?我认为前者更清晰。 - Samvar ctx = new DbContext();
ctx.Database.CommandTimeout = 120;
这可能对你有所帮助。
public class MyContext : DbContext
{
public MyContext () : base(ContextHelper.CreateConnection("my connection string"), true)
{
((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 300;
}
}
((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 300;
在 DbContext 创建器之后,!loader.IsLazy 构造函数之前:
<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext
{
public <#=code.Escape(container)#>()
: base("name=<#=container.Name#>")
{
((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 300;
<#
if (!loader.IsLazyLoadingEnabled(container))
public MyEntities()
: base("name=MyEntities")
{
((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 300;
}
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;
}
}
}
public MyEntities()
: base("name=MyEntities")
{
}
ObjectContext
为空,我会抛出自定义异常。虽然我不认为它会为空,但这比获得NullReferenceException
更有意义。ObjectContext
存储在字段中,以便可以创建属性来访问它以覆盖默认设置。
<#=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 的读/写操作和视图控制器”模板添加新的 MVC 控制器类,Visual Studio 将会给出一个错误。它将说“不支持的上下文类型”。为了解决这个问题,打开生成的“MyModel.Context.cs”类,并暂时将其继承类型更改回 DbContext
。添加完新的控制器后,可以将其改回 CustomDbContext
。
public static class DbContextExtensions
{
public static void SetCommandTimeout(this ObjectContext dbContext,
int TimeOut)
{
dbContext.CommandTimeout = TimeOut;
}
}
((IObjectContextAdapter)cx).ObjectContext.SetCommandTimeout(300);
public partial class MyEntities : DbContext
{
public MyEntities()
: base("name=MyConnectionStringName")
{
}
...
}
然后创建一个新的自定义类,作为MyEntities的包装器,如下所示:
public class MyEntitiesContainer : MyEntities
{
private static readonly int _DEFAULT_TIMEOUT = 100;
public MyEntitiesContainer()
{
((IObjectContextAdapter)this).ObjectContext.CommandTimeout = _DEFAULT_TIMEOUT;
}
//Use this method to temporarily override the default timeout
public void SetCommandTimeout(int commandTimeout)
{
((IObjectContextAdapter)this).ObjectContext.CommandTimeout = commandTimeout;
}
//Use this method to reset the timeout back to default
public void ResetCommandTimeout()
{
((IObjectContextAdapter)this).ObjectContext.CommandTimeout = _COMMAND_TIMEOUT;
}
}
using (var db = new MyEntitiesContainer()) {
db.SetCommandTimeout(300);
db.DoSomeLongCommand();
db.ResetCommandTimeout();
db.DoShorterCommand1();
db.DoShorterCommand2();
...
}
Dim objectContext As Objects.ObjectContext = CType(Me,IObjectContextAdapter).ObjectContext
objectContext.commandTimeout = connectionTimeout
我来这里是为了寻找一个设置单个命令超时时间的例子,而不是全局设置。
我想这个例子可能会对某些人有所帮助,下面是我实现它的示例:
var sqlCmd = new SqlCommand(sql, context.Database.Connection as SqlConnection);
sqlCmd.Parameters.Add(idParam);
sqlCmd.CommandTimeout = 90;
if (sqlCmd.Connection.State == System.Data.ConnectionState.Closed)
{
sqlCmd.Connection.Open();
}
sqlCmd.ExecuteNonQuery();
sqlCmd.Connection.Close();
@PerryTribolet的答案对于EF6看起来不错,但它不适用于EF5。对于EF,有一种方法可以做到这一点:创建一个ObjectContext,设置该对象的CommandTimeout,然后从ObjectContext创建一个DBContext。我设置了标志,使两个对象一起被处理。以下是VB.NET的示例:
Dim context As New ObjectContext("name=Our_Entities")
Dim dbcontext As New System.Data.Entity.DbContext(context, True)
With context
.CommandTimeout = 300 'DBCommandTimeout
End With
当然你不必使用 "With"。