İzleme ve No-Tracking sorguları karşılaştırması
Entity Framework Core değişiklik izleyicide bir varlık örneği hakkındaki bilgileri tutacağı davranış denetimlerini izleme. Bir varlık izleniyorsa, varlıkta algılanan tüm değişiklikler sırasında veritabanında kalıcı olur SaveChanges() . EF Core, bir izleme sorgusu sonucu ve değişiklik izleyicide bulunan varlıklar arasındaki gezinti özelliklerini de düzeltir.
Not
Keyless varlık türleri hiçbir şekilde izlenmez. Bu makalede varlık türleri söz konusu olduğunda, tanımlı bir anahtarı olan varlık türleri anlamına gelir.
İpucu
Bu makalenin örneğini GitHub görüntüleyebilirsiniz.
Sorguları izleme
Varsayılan olarak, varlık türleri döndüren sorgular izliyor. Bu, bu varlık örneklerinde değişiklik yapabileceğiniz ve bu değişiklikleri tarafından kalıcı hale oluşturabileceğiniz anlamına gelir SaveChanges() . Aşağıdaki örnekte, bloglarda yapılan değişiklik, sırasında veritabanı tarafından algılanır ve kalıcı hale getirilir SaveChanges() .
var blog = context.Blogs.SingleOrDefault(b => b.BlogId == 1);
blog.Rating = 5;
context.SaveChanges();
Sonuçlar bir izleme sorgusunda döndürüldüğünde, EF Core varlığın zaten bağlam içinde olup olmadığını kontrol eder. EF Core var olan bir varlığı bulursa aynı örnek döndürülür. EF Core, kaynağın geçerli ve özgün değerlerinin veritabanı değerleriyle birlikte girdisindeki özelliklerinin üzerine yazmaz. Varlık bağlamda bulunmazsa, EF Core yeni bir varlık örneği oluşturacak ve bağlamı ekleyecek. Sorgu sonuçları, içeriğe eklenen ancak henüz veritabanına kaydedilmemiş herhangi bir varlık içermiyor.
İzleme sorguları yok
Bir salt okuma senaryosunda sonuçlar kullanıldığında hiçbir izleme sorgusu yararlı değildir. Değişiklik izleme bilgilerini ayarlamaya gerek olmadığı için daha hızlı bir şekilde yürütüyoruz. Veritabanından alınan varlıkları güncelleştirmeniz gerekmiyorsa, bir izleme sorgusunun kullanılması gerekir. Tek bir sorguyu bir izleme olmayacak şekilde takas edebilirsiniz. Hiçbir izleme sorgusu, veritabanında yerel değişikliklere veya eklenen varlıklara yönelik olarak neler olduğunu temel alan sonuçları da verecektir.
var blogs = context.Blogs
.AsNoTracking()
.ToList();
Bağlam örneği düzeyinde varsayılan izleme davranışını da değiştirebilirsiniz:
context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;
var blogs = context.Blogs.ToList();
Kimlik çözümlemesi
İzleme sorgusu değişiklik izleyicisini kullandığından, EF Core izleme sorgusunda kimlik çözümlemesi yapılır. Bir varlığı oluştururken EF Core, zaten izleniyorsa değişiklik izleyicide aynı varlık örneğini döndürür. Sonuç aynı varlığı birden çok kez içeriyorsa, her oluşum için aynı örneği geri alırsınız. Hiçbir izleme sorgusu değişiklik izleyicisini kullanmaz ve kimlik çözümlemesi yapmayın. Bu nedenle, aynı varlık sonuç olarak birden çok kez yer alsa bile varlığın yeni bir örneğini geri almanız gerekir.
EF Core 5,0 ' den başlayarak, yukarıdaki davranışların her ikisini de aynı sorgu içinde birleştirebilirsiniz. Diğer bir deyişle, sonuçlarda kimlik çözümlemesi yapan bir izleme sorgusuna sahip olabilirsiniz. Aynı AsNoTracking() sorgulanabilir operatör gibi başka bir işleç ekledik AsNoTrackingWithIdentityResolution() . Ayrıca, Querytrackingbehavior sabit listesine eklenen ilişkili giriş de vardır. Sorguyu, izleme olmadan kimlik çözümlemesi kullanacak şekilde yapılandırdığınızda, her örnek yalnızca bir kez gerçekleştirilmek üzere sorgu sonuçları oluştururken arka planda tek başına değişiklik İzleyicisi kullanırız. Bu değişiklik İzleyici bağlamdan farklı olduğundan, sonuçlar bağlam tarafından izlenmez. Sorgu tam olarak numaralandırıldıktan sonra değişiklik İzleyici kapsam dışına çıkar ve gereken atık olarak toplanır.
var blogs = context.Blogs
.AsNoTrackingWithIdentityResolution()
.ToList();
İzleme ve özel tahminler
Sorgunun sonuç türü bir varlık türü olmasa bile EF Core, varsayılan olarak sonuçta bulunan varlık türlerini izlemeye devam eder. Bir anonim tür döndüren aşağıdaki sorguda, Blog sonuç kümesindeki örnekleri izlenir.
var blog = context.Blogs
.Select(
b =>
new { Blog = b, PostCount = b.Posts.Count() });
Sonuç kümesi, LINQ kompozisyonunuzdan gelen varlık türlerini içeriyorsa, EF Core bunları izler.
var blog = context.Blogs
.Select(
b =>
new { Blog = b, Post = b.Posts.OrderBy(p => p.Rating).LastOrDefault() });
Sonuç kümesi herhangi bir varlık türü içermiyorsa, izleme yapılmaz. Aşağıdaki sorguda, varlıktan bazı değerler içeren anonim bir tür döndürüyoruz (ancak gerçek varlık türünün örneklerinden hiçbiri). Sorgudan gelen hiçbir izlenen varlık yok.
var blog = context.Blogs
.Select(
b =>
new { Id = b.BlogId, b.Url });
EF Core, en üst düzey projeksiyde istemci değerlendirmesi yapmak destekler. EF Core, istemci değerlendirmesi için bir varlık örneği içeriyorsa izlenir. Burada, blog varlıkları istemci yöntemine geçirdiğimiz için StandardizeURL EF Core blog örneklerini de izlerler.
var blogs = context.Blogs
.OrderByDescending(blog => blog.Rating)
.Select(
blog => new { Id = blog.BlogId, Url = StandardizeUrl(blog) })
.ToList();
public static string StandardizeUrl(Blog blog)
{
var url = blog.Url.ToLower();
if (!url.StartsWith("http://"))
{
url = string.Concat("http://", url);
}
return url;
}
EF Core, sonuçta yer alan anahtarsız varlık örneklerini izlemez. Ancak EF Core Yukarıdaki kurallara göre bir anahtarla tüm varlık türlerinin diğer örneklerini izler.
Önceki sürümler
Sürüm 3,0 ' den önce, EF Core izlemenin nasıl yapıldığı konusunda bazı farklılıklar vardı. Önemli farklar şunlardır:
İstemci vs Server değerlendirmesi sayfasında açıklandığı gibi, 3,0 sürümünden önceki sorgunun herhangi bir bölümünde desteklenen istemci değerlendirmesi EF Core. İstemci değerlendirmesi, sonucun bir parçası olmayan varlıkların bir şekilde oluşturulmasına neden oldu. EF Core, nelerin izleneceğini algılamak için sonucu analiz eder. Bu tasarımda aşağıdaki gibi bazı farklılıklar vardı:
Yansıtmada oluşan, ancak gerçekleştirilmiş varlık örneğini döndürmeyen istemci değerlendirmesi izlenmiyor. Aşağıdaki örnek varlıkları izlememedi
blog.var blogs = context.Blogs .OrderByDescending(blog => blog.Rating) .Select( blog => new { Id = blog.BlogId, Url = StandardizeUrl(blog) }) .ToList();EF Core, bazı durumlarda LINQ kompozisyonunun geldiği nesneleri izlememedi. Aşağıdaki örnek izmedi
Post.var blog = context.Blogs .Select( b => new { Blog = b, Post = b.Posts.OrderBy(p => p.Rating).LastOrDefault() });
Sorgu sonuçları, anahtarsız varlık türleri içerdiğinde, tüm sorgu izlenmesiz hale getirilir. Diğer bir deyişle, bu, sonuçlardaki, anahtar içeren varlık türlerinin izlenmediği anlamına gelir.
EF Core izleme sorgularında kimlik çözümlemesi yapmak için kullanılır. Daha önceden döndürülen varlıkların izlenmesini sağlamak için zayıf başvurular kullandı. Bu nedenle, bir sonuç kümesi aynı varlığı çarpan bir kez içeriyorsa, her oluşum için aynı örneği elde edersiniz. Aynı kimliğe sahip önceki bir sonuç kapsam dışında gelse ve atık toplanmışsa, EF Core yeni bir örnek döndürdü.