クライアントとサーバーの評価Client vs. Server Evaluation

Entity Framework Core では、クライアント上でクエリの一部を評価し、一部をデータベースにプッシュする機能をサポートしています。Entity Framework Core supports parts of the query being evaluated on the client and parts of it being pushed to the database. クエリのどの部分がデータベースで評価されるかの識別は、データベース プロバイダーが行います。It is up to the database provider to determine which parts of the query will be evaluated in the database.

ヒント

この記事のサンプルは GitHub で確認できます。You can view this article's sample on GitHub.

クライアントの評価Client evaluation

次の例では、SQL Server データベースから返されるブログの URL を標準化するために、ヘルパー メソッドが使用されています。In the following example a helper method is used to standardize URLs for blogs that are returned from a SQL Server database. SQL Server プロバイダーはこのメソッドの実装方法に関する分析情報を保持していないため、このメソッドを SQL に変換することはできません。Because the SQL Server provider has no insight into how this method is implemented, it is not possible to translate it into SQL. クエリの他の側面はすべてデータベースで評価されますが、このメソッド経由で返された URL の受け渡しは、クライアント上で実行されます。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;
}

クライアントの評価に伴うパフォーマンスの問題Client evaluation performance issues

クライアントの評価は非常に便利な場合もありますが、一部の例では、パフォーマンスが低下する恐れがあります。While client evaluation can be very useful, in some instances it can result in poor performance. 次のクエリを検討してください。このクエリでは現在、ヘルパー メソッドがフィルター内で使用されています。Consider the following query, where the helper method is now used in a filter. データベース内ではこれを実行できないので、すべてのデータがメモリ内にプルされて、クライアント上でフィルターが適用されます。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. データ量と、そのデータがフィルターで除外される量によっては、このことがパフォーマンス低下につながります。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();

クライアントの評価の記録Client evaluation logging

既定では、クライアントの評価が実行されると、EF Core は警告を記録します。By default, EF Core will log a warning when client evaluation is performed. ログ記録の出力の表示に関する詳細については、ログ記録に関するページを参照してください。See Logging for more information on viewing logging output.

オプションの動作: クライアントの評価の例外をスローするOptional behavior: throw an exception for client evaluation

クライアントの評価が行われる場合の動作を、エラーをスローするか、または何もしないかに変更できます。You can change the behavior when client evaluation occurs to either throw or do nothing. ASP.NET Core を使用している場合、通常は DbContext.OnConfiguring または Startup.cs でコンテキストのオプションを設定するときに、この変更が行われます。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));
}