Tiempos de espera de Entity Framework
Obtengo tiempos de espera al utilizar Entity Framework (EF) cuando utilizo una importación de función que tarda más de 30 segundos en completarse. Intenté lo siguiente y no pude resolver este problema:
Agregué Default Command Timeout=300000
la cadena de conexión en el archivo App.Config en el proyecto que tiene el archivo EDMX como se sugiere aquí .
Así es como se ve mi cadena de conexión:
<add
name="MyEntityConnectionString"
connectionString="metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|
res://*/MyEntities.msl;
provider=System.Data.SqlClient;provider connection string="
Data Source=trekdevbox;Initial Catalog=StarTrekDatabase;
Persist Security Info=True;User ID=JamesTKirk;Password=IsFriendsWithSpock;
MultipleActiveResultSets=True;Default Command Timeout=300000;""
providerName="System.Data.EntityClient" />
Intenté configurar CommandTimeout en mi repositorio directamente así:
private TrekEntities context = new TrekEntities();
public IEnumerable<TrekMatches> GetKirksFriends()
{
this.context.CommandTimeout = 180;
return this.context.GetKirksFriends();
}
¿Qué más puedo hacer para que el EF deje de funcionar? Esto sólo ocurre con conjuntos de datos muy grandes. Todo funciona bien con pequeños conjuntos de datos.
Este es uno de los errores que recibo:
System.Data.EntityCommandExecutionException: se produjo un error al ejecutar la definición del comando. Consulte la excepción interna para obtener más detalles. ---> System.Data.SqlClient.SqlException: el tiempo de espera expiró. El período de tiempo de espera ha transcurrido antes de completar la operación o el servidor no responde.
Bien, hice que esto funcionara y es una tontería lo que pasó. Tenía la cadena de conexión Default Command Timeout=300000
y CommandTimeout configurado en 180. Cuando eliminé la Default Command Timeout
cadena de conexión, funcionó. Entonces, la respuesta es configurar manualmente CommandTimeout en su repositorio en su objeto de contexto de esta manera:
this.context.CommandTimeout = 180;
Aparentemente, establecer la configuración de tiempo de espera en la cadena de conexión no tiene ningún efecto.
Existe un error conocido al especificar el tiempo de espera del comando predeterminado dentro de la cadena de conexión de EF.
http://bugs.mysql.com/bug.php?id=56806
Elimine el valor de la cadena de conexión y configúrelo en el propio objeto de contexto de datos. Esto funcionará si elimina el valor conflictivo de la cadena de conexión.
Entidad Framework Core 1.0:
this.context.Database.SetCommandTimeout(180);
Marco de entidad 6:
this.context.Database.CommandTimeout = 180;
Marco de entidad 5:
((IObjectContextAdapter)this.context).ObjectContext.CommandTimeout = 180;
Entity Framework 4 y siguientes:
this.context.CommandTimeout = 180;
Si está utilizando DbContext, utilice el siguiente constructor para establecer el tiempo de espera del comando:
public class MyContext : DbContext
{
public MyContext ()
{
var adapter = (IObjectContextAdapter)this;
var objectContext = adapter.ObjectContext;
objectContext.CommandTimeout = 1 * 60; // value in seconds
}
}
Si está utilizando DbContext
EF v6+, alternativamente puede utilizar:
this.context.Database.CommandTimeout = 180;
Si está utilizando Entity Framework como yo, debe definir el tiempo de espera en la clase de inicio de la siguiente manera:
services.AddDbContext<ApplicationDbContext>(
options => options.UseSqlServer(
Configuration.GetConnectionString("DefaultConnection"),
a => a.CommandTimeout(180)));
Generalmente manejo mis operaciones dentro de una transacción . Como he experimentado, no es suficiente establecer el tiempo de espera del comando de contexto, sino que la transacción necesita un constructor con un parámetro de tiempo de espera. Tuve que establecer ambos valores de tiempo de espera para que funcionara correctamente.
int? prevto = uow.Context.Database.CommandTimeout;
uow.Context.Database.CommandTimeout = 900;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(900))) {
...
}
Al final de la función, restablezco el tiempo de espera del comando al valor anterior en anterior.
Usando EF6