用戶端與伺服器評估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

在下列範例中,會使用 Helper 方法來將從 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;
}

停用用戶端評估Disabling client evaluation

雖然用戶端評估非常實用,但在某些情況下,可能會導致效能不佳。While client evaluation can be very useful, in some instances it can result in poor performance. 請考慮下列查詢,此查詢目前會在篩選條件中使用 Helper 方法。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();

根據預設,執行用戶端評估時,EF Core 將會記錄警告。By default, EF Core will log a warning when client evaluation is performed. 如需檢視記錄輸出的詳細資訊,請參閱記錄See Logging for more information on viewing logging output. 您可以變更在用戶端評估發生而擲回或不執行任何動作時的行為。You can change the behavior when client evaluation occurs to either throw or do nothing. 這通常會在 DbContext.OnConfiguring 中為您的內容設定選項時完成,或者,如果您使用 ASP.NET Core,則是在 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));
}