2012-10-08 32 views
121

Mi comando mantiene el tiempo de espera. así que necesito cambiar el valor predeterminado de tiempo de espera del comando. Encontré "myDb.Database.Connection.ConnectionTimeout" pero es de solo lectura.Establecer el tiempo de espera de la base de datos en Entity Framework

¿Cómo puedo configurar el tiempo de espera del comando en Entity Framework 5?

+16

FYI, en EF6, 'Database.CommandTimeout' ya no es de solo lectura – itsho

+1

@itsho Estaba hablando de' Database.Connection.ConnectionTimeout'. De todos modos, diría que 'Database.CommandTimeout' es lo correcto en el caso de que su consulta sea time-outing (excepción' System.Data.Entity.Core.EntityCommandExecutionException' que contiene 'System.Data.SqlClient.SqlException: Timeout expired. '). –

+0

duplicado posible de [Entity Framework Tiempos de espera] (http://stackoverflow.com/questions/6232633/entity-framework-timeouts) –

Respuesta

149

Pruebe esto en su contexto:

public class MyDatabase : DbContext 
{ 
    public MyDatabase() 
     : base(ContextHelper.CreateConnection("Connection string"), true) 
    { 
     ((IObjectContextAdapter)this).ObjectContext.CommandTimeout = 180; 
    } 
} 

Si desea definir el tiempo de espera en la cadena de conexión, utilice el parámetro Connection Timeout al igual que en la cadena de conexión:

<connectionStrings> 

<add name="AdventureWorksEntities" 
connectionString="metadata=.\AdventureWorks.csdl|.\AdventureWorks.ssdl|.\AdventureWorks.msl; 
provider=System.Data.SqlClient;provider connection string='Data Source=localhost; 
Initial Catalog=AdventureWorks;Integrated Security=True;Connection Timeout=60; 
multipleactiveresultsets=true'" providerName="System.Data.EntityClient" /> 

</connectionStrings> 

Fuente: How to: Define the Connection String

+1

Yo recomiendo usar la versión de cadena de conexión como si se intenta acceder al 'ObjectContext' en este constructor veces los comandos de la consola de PowerShell [/ NuGet fallarán de forma circular] (http://stackoverflow.com/questions/15169281/ recibir-el-modelo-respaldar-el-contexto-contexto-ha-cambiado-en-agregar-migrar). –

+91

Tiempo de espera de conexión y CommandTimeout y dos cosas separadas. La configuración de la cadena de conexión, Tiempo de espera de conexión, no afectará la cantidad de tiempo que se ejecuta el comando (CommandTimeout). –

+0

podría deberse a que se trata de una respuesta es un año de edad, pero 'Conexión Timeout' plantea una' EntityException' "El proveedor subyacente falló en abierto". El valor real actual es 'Connect Timeout', pero parece ser ignorado por EF de todos modos. – Lankymart

17

Mi contexto parcial loo ks como:

public partial class MyContext : DbContext 
{ 
    public MyContext (string ConnectionString) 
     : base(ConnectionString) 
    { 
     this.SetCommandTimeOut(300); 
    } 

    public void SetCommandTimeOut(int Timeout) 
    { 
     var objectContext = (this as IObjectContextAdapter).ObjectContext; 
     objectContext.CommandTimeout = Timeout; 
    } 
} 

me dejó SetCommandTimeOut públicos por lo que sólo las rutinas necesito tomar un largo tiempo (más de 5 minutos) modifico en lugar de un tiempo de espera global.

7

Igual que otras respuestas, sino como un método de extensión:

static class Extensions 
{ 
    public static void SetCommandTimeout(this IObjectContextAdapter db, TimeSpan? timeout) 
    { 
     db.ObjectContext.CommandTimeout = timeout.HasValue ? (int?) timeout.Value.TotalSeconds : null; 
    } 
} 
+0

y cómo llamo a este método de extensión? –

8

extendí la respuesta de Ronnie con una implementación fluida para que pueda usarlo de esta manera:

dm.Context.SetCommandTimeout(120).Database.SqlQuery...

public static class EF 
{ 
    public static DbContext SetCommandTimeout(this DbContext db, TimeSpan? timeout) 
    { 
     ((IObjectContextAdapter)db).ObjectContext.CommandTimeout = timeout.HasValue ? (int?) timeout.Value.TotalSeconds : null; 

     return db; 
    } 

    public static DbContext SetCommandTimeout(this DbContext db, int seconds) 
    { 
     return db.SetCommandTimeout(TimeSpan.FromSeconds(seconds)); 
    } 
} 
7

En el código de constructor generado debe llamar al OnContextCreated()

añadí esta clase parcial para resolver el problema:

partial class MyContext: ObjectContext 
{ 
    partial void OnContextCreated() 
    { 
     this.CommandTimeout = 300; 
    } 
} 
123

Puede utilizar DbContext.Database.CommandTimeout = 180;

Es bastante simple y no requiere fundido.

+1

Muy útil para nosotros que usamos la forma 'Fluent API' de EF. – GoldBishop

+1

Me alegro de haber visto esto, siempre estuve (¡innecesariamente!) Cauteloso con el reparto. –

+0

en cuanto a mí, funciona incluso en EF5, gracias! – Fragment

7

Por primera base de datos Aproximación:

Podemos todavía la pusieron en un constructor, por la anulación de la ContextName.Context.tt Plantilla T4 de esta manera:

<#=Accessibility.ForType(container)#> partial class <#=code.Escape(container)#> : DbContext 
{ 
    public <#=code.Escape(container)#>() 
     : base("name=<#=container.Name#>") 
    { 
     Database.CommandTimeout = 180; 
<# 
if (!loader.IsLazyLoadingEnabled(container)) 
{ 
#> 
     this.Configuration.LazyLoadingEnabled = false; 
<# 
} 

Database.CommandTimeout = 180; es el cambio acutaly.

La salida generada es la siguiente:

public ContextName() : base("name=ContextName") 
{ 
    Database.CommandTimeout = 180; 
} 

Si cambia su modelo de base de datos, esta plantilla se mantiene, pero la clase actualy se actualizará.

+0

¿Hay alguna manera de especificar el tiempo de espera en la plantilla utilizando algún archivo de configuración? – shas

+1

no estoy seguro, si hay algo incorporado (no pude encontrar algo). Pero en lugar de hardcoding 180, puede usar ['System.Configuration.ConfigurationManager.AppSettings [" keyname "]'] (http://stackoverflow.com/questions/1189364/reading-settings-from-app-config-or- web-config-in-net) @shas –

+0

Eso es lo que estaba buscando. Gracias por tu ayuda. – shas

Cuestiones relacionadas