it-swarm.com.de

Legen Sie das Datenbank-Timeout in Entity Framework fest

Mein Befehl läuft weiter ab, daher muss der Standardwert für das Zeitlimit für Befehle geändert werden.

Ich habe gefunden myDb.Database.Connection.ConnectionTimeout, aber es ist readonly.

Wie kann ich das Befehlszeitlimit in Entity Framework 5 einstellen?

152
James

Versuchen Sie dies in Ihrem Kontext:

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

Wenn Sie das Zeitlimit in der Verbindungszeichenfolge definieren möchten, verwenden Sie Connection Timeout -Parameter wie in der folgenden Verbindungszeichenfolge:

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

Quelle: Gewusst wie: Definieren der Verbindungszeichenfolge

189

Sie können DbContext.Database.CommandTimeout = 180;

Es ist ziemlich einfach und keine Besetzung erforderlich.

166
Vu Nguyen

Mein partieller Kontext sieht so aus:

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

Ich habe SetCommandTimeOut public gelassen, damit nur die Routinen, die ich für eine lange Zeit benötige (mehr als 5 Minuten), die ich anstelle eines globalen Timeouts ändere.

20
Erik Philips

Im generierten Konstruktorcode sollte OnContextCreated() aufgerufen werden

Ich habe diese Teilklasse hinzugefügt, um das Problem zu lösen:

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

Ich habe Ronnies Antwort um eine fließende Implementierung erweitert, damit Sie sie so verwenden können:

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

Wie andere Antworten, aber als Erweiterungsmethode:

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

Für Datenbank erste Aproach:

Wir können es immer noch in einem Konstruktor setzen, indem wir das ContextName.Context.tt T4 Template auf diese Weise überschreiben:

<#=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; ist die aktuelle Änderung.

Die generierte Ausgabe lautet wie folgt:

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

Wenn Sie Ihr Datenbankmodell ändern, bleibt diese Vorlage erhalten, die aktuelle Klasse wird jedoch aktualisiert.

7