it-swarm.com.de

Entity Framework-Timeouts

Beim Verwenden eines Funktionsimports, dessen Ausführung mehr als 30 Sekunden dauert, treten Zeitüberschreitungen mit dem Entity Framework (EF) auf. Ich habe Folgendes versucht und konnte das Problem nicht beheben:

Ich habe der Verbindungszeichenfolge in der Datei App.Config in dem Projekt, in dem die EDMX-Datei wie vorgeschlagen vorliegt, Default Command Timeout=300000 Hinzugefügt hier .

So sieht meine Verbindungszeichenfolge 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, das CommandTimeout direkt in meinem Repository festzulegen:

private TrekEntities context = new TrekEntities();

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

Was kann ich noch tun, um das Zeitlimit für die EF zu verringern? Dies geschieht nur bei sehr großen Datenmengen. Alles funktioniert gut mit kleinen Datensätzen.

Hier ist einer der Fehler, die ich erhalte:

System.Data.EntityCommandExecutionException: Beim Ausführen der Befehlsdefinition ist ein Fehler aufgetreten. Einzelheiten finden Sie in der inneren Ausnahme. ---> System.Data.SqlClient.SqlException: Timeout abgelaufen. Das Zeitlimit, das vor Abschluss des Vorgangs verstrichen ist, oder der Server reagiert nicht.


OK - ich habe das zum Laufen gebracht und es ist albern, was passiert ist. Ich hatte sowohl die Verbindungszeichenfolge mit Default Command Timeout=300000 Als auch das CommandTimeout auf 180 gesetzt. Als ich die Default Command Timeout Aus der Verbindungszeichenfolge entfernte, funktionierte es. Die Antwort ist also, das CommandTimeout in Ihrem Repository auf Ihrem Kontextobjekt wie folgt manuell festzulegen:

this.context.CommandTimeout = 180;

Anscheinend hat das Festlegen der Timeout-Einstellungen in der Verbindungszeichenfolge keine Auswirkungen darauf.

297
Halcyon

Es ist ein Fehler beim Festlegen des Standardbefehlszeitlimits in der EF-Verbindungszeichenfolge bekannt.

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

Entfernen Sie den Wert aus der Verbindungszeichenfolge und legen Sie ihn für das Datenkontextobjekt selbst fest. 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 darunter:

this.context.CommandTimeout = 180;
518
Chev

Wenn Sie einen DbContext verwenden, verwenden Sie den folgenden Konstruktor, um das Befehlszeitlimit festzulegen:

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

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

this.context.Database.CommandTimeout = 180;
37
Paul

Normalerweise erledige ich meine Operationen innerhalb einer Transaktion. Wie ich erfahren habe, reicht es nicht aus, das Zeitlimit für den Kontextbefehl festzulegen, aber für die Transaktion ist ein Konstruktor mit einem Zeitlimitparameter erforderlich. 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 habe ich das Befehls-Timeout auf den vorherigen Wert in prevto zurückgesetzt.

Verwendung von EF6

9
pillesoft

Wenn Sie wie ich Entity Framework verwenden, sollten Sie die Klasse Timeout beim Start wie folgt definieren:

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

Ich weiß, dass dies ein sehr alter Thread ist, aber EF hat dies immer noch nicht behoben. Für Benutzer, die automatisch generiertes DbContext verwenden, kann das Zeitlimit mithilfe des folgenden Codes manuell festgelegt werden.

public partial class SampleContext : DbContext
{
    public SampleContext()
        : base("name=SampleContext")
    {
        this.SetCommandTimeOut(180);
    }

    public void SetCommandTimeOut(int Timeout)
    {
        var objectContext = (this as IObjectContextAdapter).ObjectContext;
        objectContext.CommandTimeout = Timeout;
    }
3
Shiva N

Das habe ich finanziert. Vielleicht hilft es jemandem:

Auf geht's:

Wenn Sie LINQ mit EF verwenden und nach bestimmten Elementen in der Liste suchen, gehen Sie wie folgt vor:

await context.MyObject1.Include("MyObject2").Where(t => IdList.Contains(t.MyObjectId)).ToListAsync();

alles läuft gut, bis IdList mehr als eine Id enthält.

Das Timeout-Problem tritt auf, wenn die Liste nur eine ID enthält. Um das Problem zu beheben, verwenden Sie die if-Bedingung, um die Anzahl der IDs in der IdList zu überprüfen.

Beispiel:

if (IdList.Count == 1)
{
    result = await entities. MyObject1.Include("MyObject2").Where(t => IdList.FirstOrDefault()==t. MyObjectId).ToListAsync();
}
else
{
    result = await entities. MyObject1.Include("MyObject2").Where(t => IdList.Contains(t. MyObjectId)).ToListAsync();
}

Erläuterung:

Versuchen Sie einfach, Sql Profiler zu verwenden und überprüfen Sie die von Entity frameeork generierte Select-Anweisung. …

1
tosjam

Wenn Sie DbContext und EF v6 + verwenden, können Sie die Eigenschaft CommandTimeout verwenden

this.context.Database.CommandTimeout = 180;

1
A.M. Patel