web-dev-qa-db-fra.com

Définir le délai d'expiration de la base de données dans Entity Framework

Ma commande continue à expirer, je dois donc modifier la valeur de délai d'expiration de la commande par défaut.

J'ai trouvé myDb.Database.Connection.ConnectionTimeout, mais c'est readonly.

Comment définir le délai d’expiration de la commande dans Entity Framework 5 ?

152
James

Essayez ceci dans votre contexte:

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

Si vous souhaitez définir le délai d'expiration dans la chaîne de connexion, utilisez le paramètre Connection Timeout comme dans la chaîne de connexion suivante:

<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>

Source: Comment: définir la chaîne de connexion

189

Vous pouvez utiliser DbContext.Database.CommandTimeout = 180;

C'est assez simple et aucun casting requis.

166
Vu Nguyen

Mon contexte partiel ressemble à:

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;
    }
}

J'ai laissé SetCommandTimeOut public afin que je ne modifie que les routines dont je dois prendre le temps (plus de 5 minutes) au lieu d'un délai d'expiration global.

20
Erik Philips

Dans le code constructeur généré, il devrait appeler OnContextCreated()

J'ai ajouté cette classe partielle pour résoudre le problème:

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

J'ai prolongé la réponse de Ronnie avec une implémentation fluide afin que vous puissiez l'utiliser comme suit:

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));
    } 
}
8
Timmerz

Identique aux autres réponses mais en tant que méthode d'extension:

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

Pour la base de données d'abord

Nous pouvons toujours le définir dans un constructeur, en remplaçant le modèle ContextName.Context.tt T4 de la manière suivante:

<#=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; est le changement effectif.

La sortie générée est la suivante:

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

Si vous modifiez votre modèle de base de données, ce modèle reste, mais la classe actuelle sera mise à jour.

7