394 Stimmen

Entity Framework Zeitüberschreitungen

Ich erhalte Timeouts bei der Verwendung von Entity Framework (EF), wenn ich einen Funktionsimport verwende, der über 30 Sekunden dauert. Ich habe Folgendes versucht und konnte dieses Problem nicht lösen:

Ich fügte hinzu Default Command Timeout=300000 an die Verbindungszeichenfolge in der Datei App.Config Datei in dem Projekt, das die EDMX-Datei enthält, wie vorgeschlagen aquí .

So sieht mein Verbindungsstring aus:

<add 
    name="MyEntityConnectionString" 
    connectionString="metadata=res://*/MyEntities.csdl|res://*/MyEntities.ssdl|
       res://*/MyEntities.msl;
       provider=System.Data.SqlClient;provider connection string=&quot;
       Data Source=trekdevbox;Initial Catalog=StarTrekDatabase;
       Persist Security Info=True;User ID=JamesTKirk;Password=IsFriendsWithSpock;
       MultipleActiveResultSets=True;Default Command Timeout=300000;&quot;"
    providerName="System.Data.EntityClient" />

Ich habe versucht, den CommandTimeout in meinem Repository direkt wie folgt zu setzen:

private TrekEntities context = new TrekEntities();

public IEnumerable<TrekMatches> GetKirksFriends()
{
    this.context.CommandTimeout = 180;
    return this.context.GetKirksFriends();
}

Was kann ich sonst noch tun, um das EF aus der Zeit zu bringen? Das passiert nur bei sehr großen Datensätzen. Bei kleinen Datensätzen funktioniert alles einwandfrei.

Hier ist eine der Fehlermeldungen, die ich erhalte:

System.Data.EntityCommandExecutionException: Bei der Ausführung der Befehlsdefinition ist ein Fehler aufgetreten. Siehe die innere Ausnahme für Details. ---> System.Data.SqlClient.SqlException: Zeitüberschreitung abgelaufen. Die Timeout-Periode ist vor dem Abschluss des Vorgangs abgelaufen, oder der Server antwortet nicht.


OK - ich habe das zum Laufen gebracht und es ist dumm, was passiert ist. Ich hatte sowohl die Verbindungszeichenfolge mit Default Command Timeout=300000 und das CommandTimeout auf 180 gesetzt. Als ich die Default Command Timeout aus dem Verbindungsstring zu entfernen, hat es funktioniert. Die Antwort ist also, den CommandTimeout manuell in Ihrem Repository auf Ihrem Kontextobjekt wie folgt zu setzen:

this.context.CommandTimeout = 180;

Offenbar hat das Setzen der Timeout-Einstellungen in der Verbindungszeichenfolge keine Auswirkung darauf.

657voto

Chev Punkte 56446

Es gibt einen bekannten Fehler bei der Angabe des Standard-Befehls-Timeouts innerhalb der EF-Verbindungszeichenfolge.

http://bugs.mysql.com/bug.php?id=56806

Entfernen Sie den Wert aus der Verbindungszeichenfolge und setzen Sie ihn auf das Datenkontextobjekt selbst. Dies funktioniert, wenn Sie den widersprüchlichen Wert aus der Verbindungszeichenfolge entfernen.

Entity Framework Core 1.0:

this.context.Database.SetCommandTimeout(180);

Entity Framework 6:

this.context.Database.CommandTimeout = 180;

Entity Framework 5:

((IObjectContextAdapter)this.context).ObjectContext.CommandTimeout = 180;

Entity Framework 4 und niedriger:

this.context.CommandTimeout = 180;

106voto

saille Punkte 8687

Wenn Sie einen DbContext verwenden, verwenden Sie den folgenden Konstruktor, um den Befehls-Timeout festzulegen:

public class MyContext : DbContext
{
    public MyContext ()
    {
        var adapter = (IObjectContextAdapter)this;
        var objectContext = adapter.ObjectContext;
        objectContext.CommandTimeout = 1 * 60; // value in seconds
    }
}

54voto

Paul Punkte 491

Wenn Sie Folgendes verwenden DbContext und EF v6+, alternativ können Sie verwenden:

this.context.Database.CommandTimeout = 180;

21voto

parismiguel Punkte 546

Wenn Sie wie ich Entity Framework verwenden, sollten Sie die Klasse Time out on Startup wie folgt definieren:

 services.AddDbContext<ApplicationDbContext>(options => options.UseSqlServer(Configuration.GetConnectionString("DefaultConnection"), o => o.CommandTimeout(180)));

15voto

pillesoft Punkte 486

Normalerweise wickle ich meine Operationen innerhalb einer Transaktion . Wie ich erfahren habe, reicht es nicht aus, den Timeout für den Kontextbefehl festzulegen, sondern die Transaktion benötigt einen Konstruktor mit einem Timeout-Parameter. Ich musste beide Timeout-Werte einstellen, damit es richtig funktioniert.

int? prevto = uow.Context.Database.CommandTimeout;
uow.Context.Database.CommandTimeout = 900;
using (TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, TimeSpan.FromSeconds(900))) {
...
}

Am Ende der Funktion setze ich die Befehlszeitüberschreitung auf den vorherigen Wert in prevto zurück.

Verwendung von EF6

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X