Imposta il timeout del database in Entity Framework


164

Il mio comando mantiene il timeout, quindi devo modificare il valore di timeout del comando predefinito.

Ho trovato myDb.Database.Connection.ConnectionTimeout, ma lo è readonly.

Come posso impostare il timeout del comando in Entity Framework 5 ?


20
Cordiali saluti, L'EF6, Database.CommandTimeoutnon è più sola lettura
itsho

2
@itsho Stava parlando Database.Connection.ConnectionTimeout. Ad ogni modo, direi che Database.CommandTimeoutè la cosa giusta nel caso in cui la query sia in timeout ( System.Data.Entity.Core.EntityCommandExecutionExceptioncontenente eccezioni System.Data.SqlClient.SqlException: Timeout expired.).
David Ferenczy Rogožan,

2
Possibile duplicato dei timeout
Tim Pohlmann,

1
Suppongo che in realtà non ti interessi del timeout CONNECTION, ma invece desideri regolare il timeout COMMAND.
Degno7

Risposte:


199

Prova questo nel tuo contesto:

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

Se si desidera definire il timeout nella stringa di connessione, utilizzare il Connection Timeoutparametro come nella seguente stringa di connessione:

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

Fonte: Procedura: definire la stringa di connessione


1
Consiglierei di utilizzare la versione della stringa di connessione come se si provasse ad accedere a ObjectContextin questo costruttore a volte i comandi della console PowerShell / NuGet falliranno in modo circolare .
Kevin Gorski,

130
Timeout connessione e CommandTimeout e due cose separate. L'impostazione della stringa di connessione, Timeout connessione, non influisce sul tempo di esecuzione del comando (CommandTimeout).
Clay Lenhart,

3
Il mio problema era diverso. Ho avuto il timeout durante le migrazioni. EF ha una proprietà simile da impostare per l'utilizzo durante le migrazioni: msdn.microsoft.com/en-us/library/…
Karsten

2
A seconda della versione di EF che usi, vedi questa risposta per avere un'idea delle diverse API in come specificare la proprietà CommandTimeout.
Jim Aho,

1
Non funziona per me (connessione vs comando non è la stessa cosa che sospetto). Questo post risolto se stackoverflow.com/questions/6232633/entity-framework-timeouts
Jezbers

181

Puoi usare DbContext.Database.CommandTimeout = 180;

È piuttosto semplice e non è richiesto alcun cast.


1
Molto utile per noi che usano la Fluent APIforma di EF.
GoldBishop,

20

Il mio contesto parziale è simile a:

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

Ho lasciato SetCommandTimeOutpubblico quindi solo le routine che devo impiegare a lungo (più di 5 minuti) le modifico invece di un timeout globale.


9

Nel codice del costruttore generato dovrebbe chiamare OnContextCreated()

Ho aggiunto questa classe parziale per risolvere il problema:

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

8

Ho esteso la risposta di Ronnie con un'implementazione fluida in modo da poterla usare così:

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

Per il primo approccio al database:

Possiamo ancora impostarlo in un costruttore, sovrascrivendo il modello T4 ContextName.Context.tt in questo modo:

<#=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; è il cambiamento di acutaly.

L'output generato è questo:

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

Se si modifica il modello di database, questo modello rimane, ma la classe effettiva verrà aggiornata.


È possibile specificare il timeout in Template utilizzando un file di configurazione.?
sha

1
non sono sicuro, se c'è qualcosa dentro (non sono riuscito a trovare qualcosa). Invece di hardcoding 180, puoi usare System.Configuration.ConfigurationManager.AppSettings["keyname"]@shas
Christian Gollhardt il

7

Come le altre risposte, ma come metodo di estensione:

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

e come posso chiamare questo metodo di estensione?
Wanderson López,

1

Ho appena riscontrato questo problema e l'ho risolto aggiornando il mio file di configurazione dell'applicazione. Per la connessione in questione, specificare "Timeout connessione = 60" (Sto utilizzando Entity Framework versione 5.0.0.0)

Impostazione ConnectionTimeout


Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.