Asynchrone Programmierung

Asynchrone Vorgänge vermeiden das Blockieren eines Threads, während die Abfrage in der Datenbank ausgeführt wird. Asynchrone Vorgänge sind wichtig, um eine reaktionsfähige Benutzeroberfläche in Rich-Client-Anwendungen beizubehalten, und kann auch den Durchsatz in Webanwendungen erhöhen, in denen sie den Thread freigeben, um andere Anforderungen in Webanwendungen zu nutzen.

Nach dem .NET-Standard stellt EF Core asynchrone Gegenstücke zu allen synchronen Methoden bereit, die I/O ausführen. Diese haben dieselben Effekte wie die Synchronisierungsmethoden und können mit den C# async - und await Schlüsselwörtern verwendet werden. Anstatt beispielsweise DbContext.SaveChanges zu verwenden, der einen Thread blockiert, während datenbank-I/O ausgeführt wird, kann DbContext.SaveChangesAsync verwendet werden:

var blog = new Blog { Url = "http://sample.com" };
context.Blogs.Add(blog);
await context.SaveChangesAsync();

Weitere Informationen finden Sie in den allgemeinen Asynchronen C#-Programmierdokumenten.

Warnung

EF Core unterstützt nicht die Ausführung mehrerer paralleler Vorgänge, die auf derselben Kontextinstanz ausgeführt werden. Sie sollten immer auf den Abschluss eines Vorgangs warten, bevor Sie den nächsten starten. In der Regel erfolgt dies für alle asynchronen Vorgänge durch das Schlüsselwort await.

Warnung

Die asynchrone Implementierung von Microsoft.Data.SqlClient hat leider einige bekannte Probleme (z. B. #593, #601 und andere).

Hinweis

EF Core übergibt Abbruchtoken bis zum zugrunde liegenden Datenbankanbieter (z. B. Microsoft.Data.SqlClient). Diese Token können berücksichtigt oder nicht berücksichtigt werden – lesen Sie die Dokumentation Ihres Datenbankanbieters.

Async LINQ-Operatoren

Um die Ausführung von LINQ-Abfragen asynchron zu unterstützen, stellt EF Core eine Reihe asynchroner Erweiterungsmethoden bereit, die die Abfrage ausführen und Ergebnisse zurückgeben. Diese Gegenstücken zu den Standard-, synchronen LINQ-Operatoren umfassen ToListAsync, SingleAsync, , AsAsyncEnumerableusw.:

var blogs = await context.Blogs.Where(b => b.Rating > 3).ToListAsync();

Beachten Sie, dass es keine asynchronen Versionen einiger LINQ-Operatoren gibt, z Where . B. oder OrderBy, da diese nur die LINQ-Ausdrucksstruktur erstellen und die Abfrage nicht in der Datenbank ausführen lassen. Nur Operatoren, die die Abfrageausführung verursachen, verfügen über asynchrone Gegenstücke.

Wichtig

Die asynchronen Erweiterungsmethoden von EF Core werden im Namespace Microsoft.EntityFrameworkCore definiert. Dieser Namespace muss importiert werden, damit die Methoden verfügbar sind.

Clientseitige asynchrone LINQ-Operatoren

Die oben beschriebenen asynchronen LINQ-Operatoren können nur für EF-Abfragen verwendet werden – Sie können sie nicht mit clientseitigen LINQ to Objects Abfrage verwenden. Um clientseitige asynchrone LINQ-Vorgänge außerhalb von EF auszuführen, verwenden Sie das System.Linq.Async Paket. Dieses Paket kann besonders nützlich sein, um Vorgänge auf dem Client auszuführen, die für die Auswertung auf dem Server nicht übersetzt werden können.

In EF Core 6.0 und niedriger führt das Verweisen System.Linq.Async leider zu mehrdeutigen Aufrufkompilierungsfehlern auf LINQ-Operatoren, die auf DIE DBSets von EF angewendet werden. Dies macht es schwierig, ef und System.Linq.Async im gleichen Projekt zu verwenden. Um dieses Problem zu umgehen, fügen Sie AsQueryable Ihr DbSet hinzu:

var groupedHighlyRatedBlogs = await context.Blogs
    .AsQueryable()
    .Where(b => b.Rating > 3) // server-evaluated
    .AsAsyncEnumerable()
    .GroupBy(b => b.Rating) // client-evaluated
    .ToListAsync();