Clientauswertung im Vergleich zur ServerauswertungClient vs. Server Evaluation

Entity Framework Core unterstützt Teile der Abfrage, die auf dem Client ausgewertet werden, und Teile der Abfrage, die mithilfe von Push in die Datenbank übertragen werden.Entity Framework Core supports parts of the query being evaluated on the client and parts of it being pushed to the database. Der Datenbankanbieter bestimmt, welche Teile der Abfrage in der Datenbank ausgewertet werden.It is up to the database provider to determine which parts of the query will be evaluated in the database.

Tipp

Das in diesem Artikel verwendete Beispiel finden Sie auf GitHub.You can view this article's sample on GitHub.

ClientauswertungClient evaluation

Im folgenden Beispiel werden URLs für Blogs, die von einer SQL Server-Datenbank zurückgegeben werden, mit einer Hilfsmethode standardisiert.In the following example a helper method is used to standardize URLs for blogs that are returned from a SQL Server database. Da der SQL Server-Anbieter keinen Einblick darin hat, wie diese Methode implementiert wird, kann sie nicht in SQL verschoben werden.Because the SQL Server provider has no insight into how this method is implemented, it is not possible to translate it into SQL. Alle anderen Aspekte der Abfrage werden in der Datenbank ausgewertet. Die Rückgabe der URL über diese Methode erfolgt jedoch über den Client.All other aspects of the query are evaluated in the database, but passing the returned URL through this method is performed on the client.

var blogs = context.Blogs
    .OrderByDescending(blog => blog.Rating)
    .Select(blog => new
    {
        Id = blog.BlogId,
        Url = StandardizeUrl(blog.Url)
    })
    .ToList();
public static string StandardizeUrl(string url)
{
    url = url.ToLower();

    if (!url.StartsWith("http://"))
    {
        url = string.Concat("http://", url);
    }

    return url;
}

Deaktivieren der ClientauswertungDisabling client evaluation

Die Clientauswertung kann sehr hilfreich sein, in manchen Fällen kann sie jedoch auch zu einer schlechten Leistung führen.While client evaluation can be very useful, in some instances it can result in poor performance. Betrachten Sie die folgende Abfrage, in der die Hilfsmethode jetzt in einem Filter verwendet wird.Consider the following query, where the helper method is now used in a filter. Da dieser Vorgang nicht in der Datenbank durchgeführt werden kann, werden sämtliche Daten mithilfe von Pull in den Speicher übertragen. Anschließend wird der Filter auf den Client angewendet.Because this can't be performed in the database, all the data is pulled into memory and then the filter is applied on the client. Abhängig vom Umfang der Daten und davon, wie viele dieser Daten herausgefiltert werden, könnte dies zu einer schlechten Leistung führen.Depending on the amount of data, and how much of that data is filtered out, this could result in poor performance.

var blogs = context.Blogs
    .Where(blog => StandardizeUrl(blog.Url).Contains("dotnet"))
    .ToList();

Standardmäßig protokolliert EF Core bei der Durchführung einer Auswertung eine Warnung.By default, EF Core will log a warning when client evaluation is performed. Weitere Informationen zum Anzeigen von Protokollierungsausgaben finden Sie unter Protokollierung.See Logging for more information on viewing logging output. Sie können das Verhalten bei einer Clientauswertung auslösen oder nichts unternehmen.You can change the behavior when client evaluation occurs to either throw or do nothing. Dies geschieht, wenn die Optionen für Ihren Kontext – normalerweise in DbContext.OnConfiguring oder Startup.cs – bei Verwendung von ASP.NET Core eingerichtet werden.This is done when setting up the options for your context - typically in DbContext.OnConfiguring, or in Startup.cs if you are using ASP.NET Core.

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying;Trusted_Connection=True;")
        .ConfigureWarnings(warnings => warnings.Throw(RelationalEventId.QueryClientEvaluationWarning));
}