İstemci ve Sunucu Değerlendirmesi karşılaştırması
Genel bir kural Entity Framework Core sunucu üzerinde bir sorguyu mümkün olduğunca değerlendirmeye çalışır. EF Core, sorgunun parçalarını istemci tarafında değerlendirilecek parametrelere dönüştürür. Sorgunun geri kalanı (oluşturulan parametrelerle birlikte), sunucuda değerlendirilecek eşdeğer veritabanı sorgusunu belirlemek için veritabanı sağlayıcısına verilir. EF Core üst düzey projeksiyonda kısmi istemci değerlendirmesini destekler (temelde son Select() çağrısı). Sorgunun üst düzey projeksiyonu sunucuya çevrilenene kadar EF Core gerekli verileri sunucudan getirir ve sorgunun istemcide kalan bölümlerini değerlendirir. Bu EF Core, sunucuya çevrilen üst düzey projeksiyon dışında herhangi bir yerde bir ifade algılarsa, bir çalışma zamanı özel durumu oluşturur. Sunucuya nelerin çevrile EF Core belirlemek için bkz. Sorguların çalışması.
Not
Sürüm 3.0'dan Entity Framework Core sorgunun herhangi bir yerinde istemci değerlendirmesi destekledi. Daha fazla bilgi için önceki sürümler bölümüne bakın.
İpucu
Bu makalenin örneğini daha sonra GitHub.
Üst düzey projeksiyonda istemci değerlendirmesi
Aşağıdaki örnekte, blogların URL'lerini standart hale getirebilirsiniz ve bu yöntem bir SQL Server döndürülür. Bu SQL Server sağlayıcının bu yöntemin nasıl uygulandığını kavraması mümkün SQL. Sorgunun diğer tüm yönleri veritabanında değerlendirilir, ancak döndürülen bu yöntem aracılığıyla geçirme URL istemcide yapılır.
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;
}
Desteklenmeyen istemci değerlendirmesi
İstemci değerlendirmesi yararlı olabilir, ancak bazen düşük performansa neden olabilir. Yardımcı yönteminin artık where filtresinde kullanılan aşağıdaki sorguyu göz önünde bulundurabilirsiniz. Filtre veritabanına uygulanamayay olduğundan, filtreyi istemciye uygulamak için tüm verilerin belleğe çekilerek uygulanması gerekir. Filtreye ve sunucuya ilişkin veri miktarına bağlı olarak, istemci değerlendirmesi düşük performansa neden olabilir. Bu Entity Framework Core istemci değerlendirmesini engeller ve bir çalışma zamanı özel durumu oluşturur.
var blogs = context.Blogs
.Where(blog => StandardizeUrl(blog.Url).Contains("dotnet"))
.ToList();
Açık istemci değerlendirmesi
Aşağıdaki gibi bazı durumlarda açıkça istemci değerlendirmesine zorlamanız gerekir
- Veri miktarı küçüktür, bu nedenle istemcide değerlendirme büyük bir performans cezasına neden olmaz.
- Kullanılan LINQ işlecinin sunucu tarafı çevirisi yoktur.
Böyle durumlarda, veya ( veya zaman uyumsuz için) gibi yöntemleri çağırarak istemci değerlendirmesini AsEnumerableToList açıkça AsAsyncEnumerableToListAsync kabulebilirsiniz. kullanarak sonuçları akışla akar, ancak kullanmak ek bellek de alan bir liste oluşturarak AsEnumerableToList arabelleğe alma neden olur. Birden çok kez numaralandırdıysanız, veritabanında yalnızca bir sorgu olduğu için sonuçların bir listede depolanması daha fazla yardımcı olur. Belirli bir kullanım durumuna bağlı olarak, hangi yöntemin durum için daha yararlı olduğunu değerlendirmeniz gerekir.
var blogs = context.Blogs
.AsEnumerable()
.Where(blog => StandardizeUrl(blog.Url).Contains("dotnet"))
.ToList();
İpucu
kullanıyorsanız ve sorguyu istemci tarafında daha fazla oluşturmak istiyorsanız, zaman uyumsuz numaralandırılabilirler için işleçleri tanımlayan AsAsyncEnumerableAsAsyncEnumerable kitaplığını kullanabilirsiniz. Daha fazla bilgi için bkz. istemci tarafı linq işleçleri.
İstemci değerlendirmesinde olası bellek sızıntısı
Sorgu çevirisi ve derleme pahalı olduğu için EF Core sorgu planını önbelleğe alıyor. Önbelleğe alınan temsilci, üst düzey projeksiyon için istemci değerlendirmesi yaparken istemci kodunu kullanabilir. EF Core ağacın istemci tarafından değerlendirilen bölümleri için parametreler oluşturur ve parametre değerlerini değiştirerek sorgu planını yeniden kullanır. Ancak ifade ağacının belirli sabitleri parametrelere dönüştürüle değildir. Önbelleğe alınan temsilci böyle sabitler içeriyorsa, bu nesnelere hala başvurulmalarına rağmen çöp toplanabilir. Böyle bir nesne içinde bir DbContext veya başka hizmetler içeriyorsa, uygulamanın bellek kullanımının zaman içinde büyümesine neden olabilir. Bu davranış genellikle bir bellek sızıntısının işaretidir. EF Core, geçerli veritabanı sağlayıcısı kullanılarak eşlenmemiş bir türün sabitleri olduğunda bir özel durum oluşturur. Yaygın nedenler ve çözümleri şunlardır:
- Örnek yöntemi kullanma:İstemci projeksiyonu içinde örnek yöntemleri kullanırken ifade ağacı örneğin sabitini içerir. Yönteminiz örnekten herhangi bir veri kullanmazsa, yöntemini statik hale kullanmayı göz önünde bulundurabilirsiniz. Yöntem gövdesinde örnek verilerine ihtiyacınız varsa, belirli verileri yöntemine bağımsız değişken olarak iletir.
- Yöntemine sabit bağımsız değişkenler geçirme:Bu durum genellikle istemci yöntemine bir bağımsız değişken kullanılarak ortaya çıkar. bağımsız değişkenlerini veritabanı sağlayıcısı tarafından eşlenen birden çok skaler bağımsız değişkene bölmeyi göz önünde bulundurabilirsiniz.
- Diğer sabitler:Başka bir durumda bir sabitle karşı karşıya kalırsanız, sabitin işleme için gerekli olup olmadığını değerlendirin. Sabitin olması gerekiyorsa veya yukarıdaki durumlardan bir çözüm kullanasanız, değeri depolamak ve sorguda yerel değişken kullanmak için bir yerel değişken oluşturun. EF Core yerel değişkeni bir parametreye dönüştürür.
Önceki sürümler
Aşağıdaki bölüm, 3.0 EF Core önceki sürümler için geçerlidir.
Eski EF Core sürümleri yalnızca üst düzey yansıtmayı değil, sorgunun herhangi bir bölümünde istemci değerlendirmesini desteklemektedir. Bu nedenle Desteklenmeyen istemci değerlendirmesi bölümünde gönderilene benzer sorgular düzgün çalıştı. Bu davranış, fark edemeyen performans sorunlarına neden EF Core bir istemci değerlendirme uyarısı günlüğe kaydedilir. Günlük çıkışını görüntüleme hakkında daha fazla bilgi için bkz. Günlüğe kaydetme.
İsteğe EF Core bir özel durum oluşturur veya istemci değerlendirmesi yaparken hiçbir şey yapma (yansıtma dışında) için varsayılan davranışı değiştirmenizi sağlar. Özel durum atma davranışı 3.0'daki davranışa benzer. Davranışı değiştirmek için, bağlamınıza yönelik seçenekleri ayarlarken ( genellikle içinde veya içinde) uyarıları yapılandırmanız DbContext.OnConfiguringStartup.cs 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));
}