Aracılığıyla paylaş


İzleme ve İzleme Olmayan Sorgular karşılaştırması

Entity Framework Core'un bir varlık örneği hakkındaki bilgileri değişiklik izleyicisinde tutarak davranış denetimlerini izleme. Bir varlık izlenirse, varlıkta algılanan tüm değişiklikler sırasında SaveChangesveritabanında kalıcı hale gelir. EF Core ayrıca bir izleme sorgusu sonucundaki varlıklar ile değişiklik izleyicisindeki varlıklar arasındaki gezinti özelliklerini de düzeltir.

Dekont

Anahtarsız varlık türleri hiçbir zaman izlenmez. Bu makalede varlık türlerinden bahsedildiği her yerde, anahtarı tanımlanmış varlık türlerine başvurur.

Bahşiş

Bu makalenin örneğini GitHub'da görüntüleyebilirsiniz.

sorguları izleme

Varsayılan olarak, varlık türlerini döndüren sorgular izlenir. İzleme sorgusu, varlık örneklerinde yapılan tüm değişikliklerin tarafından SaveChangeskalıcı olduğu anlamına gelir. Aşağıdaki örnekte, blog derecelendirmesindeki değişiklik algılanır ve sırasında SaveChangesveritabanında kalıcı hale gelir:

var blog = context.Blogs.SingleOrDefault(b => b.BlogId == 1);
blog.Rating = 5;
context.SaveChanges();

Sonuçlar bir izleme sorgusunda döndürülürken EF Core varlığın zaten bağlamda olup olmadığını denetler. EF Core mevcut bir varlığı bulursa aynı örnek döndürülür ve bu da daha az bellek kullanabilir ve izleme olmayan sorgudan daha hızlı olabilir. EF Core, girdideki varlığın özelliklerinin geçerli ve özgün değerlerinin üzerine veritabanı değerleri yazmaz. Varlık bağlamda bulunmazsa EF Core yeni bir varlık örneği oluşturur ve bağlama ekler. Sorgu sonuçları bağlama eklenen ancak henüz veritabanına kaydedilmeyen herhangi bir varlık içermez.

İzlemesiz sorgular

İzlemesiz sorgular, sonuçlar salt okunur bir senaryoda kullanıldığında kullanışlıdır. Değişiklik izleme bilgilerini ayarlamaya gerek olmadığından, bunlar genellikle daha hızlı yürütülür. Veritabanından alınan varlıkların güncelleştirilmesi gerekmiyorsa, izleme sorgusu kullanılmalıdır. Tek bir sorgu izleme olmayacak şekilde ayarlanabilir. İzlememe sorgusu, yerel değişiklikleri veya eklenen varlıkları göz ardı ederek veritabanındakilere göre de sonuç verir.

var blogs = context.Blogs
    .AsNoTracking()
    .ToList();

Varsayılan izleme davranışı bağlam örneği düzeyinde değiştirilebilir:

context.ChangeTracker.QueryTrackingBehavior = QueryTrackingBehavior.NoTracking;

var blogs = context.Blogs.ToList();

Sonraki bölümde, izleme olmayan sorgunun izleme sorgusundan daha az verimli olabileceği zamanlar açıklanmaktadır.

Kimlik çözümlemesi

İzleme sorgusu değişiklik izleyicisini kullandığından EF Core, bir izleme sorgusunda kimlik çözümlemesi yapar. Bir varlığı oluştururken EF Core, zaten izleniyorsa değişiklik izleyicisinden aynı varlık örneğini döndürür. Sonuç aynı varlığı birden çok kez içeriyorsa, her oluşum için aynı örnek döndürülür. İzlemesiz sorgular:

  • Değişiklik izleyicisini kullanmayın ve kimlik çözümlemesi yapmayın.
  • Sonuçta aynı varlık birden çok kez bulunsa bile varlığın yeni bir örneğini döndürür.

İzleme ve izleme yok aynı sorguda birleştirilebilir. Başka bir ifadeyle, sonuçlarda kimlik çözümlemesi yapan bir izleme yok sorgunuz olabilir. Sorgulanabilir işleç gibi AsNoTracking başka bir işleç AsNoTrackingWithIdentityResolution<TEntity>(IQueryable<TEntity>)ekledik. Numaralandırmaya eklenen QueryTrackingBehavior ilişkili giriş de vardır. Kimlik çözümlemesini kullanmak için sorgu izleme olmadan yapılandırıldığında, sorgu sonuçları oluşturulurken arka planda tek başına bir değişiklik izleyicisi kullanılır, böylece her örnek yalnızca bir kez gerçekleştirilir. Bu değişiklik izleyicisi bağlamdakinden farklı olduğundan, sonuçlar bağlam tarafından izlenmez. Sorgu tam olarak numaralandırıldıktan sonra, değişiklik izleyicisi kapsam dışına çıkar ve gerektiği gibi çöp toplanır.

var blogs = context.Blogs
    .AsNoTrackingWithIdentityResolution()
    .ToList();

Varsayılan izleme davranışını yapılandırma

Kendinizi birçok sorgu için izleme davranışını değiştirirken bulursanız, bunun yerine varsayılanı değiştirmek isteyebilirsiniz:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder
        .UseSqlServer(@"Server=(localdb)\mssqllocaldb;Database=EFQuerying.Tracking;Trusted_Connection=True;ConnectRetryCount=0")
        .UseQueryTrackingBehavior(QueryTrackingBehavior.NoTracking);
}

Bu, tüm sorgularınızın varsayılan olarak izlenmemesini sağlar. Belirli sorguları izlemek için ekleme AsTracking yapmaya devam edebilirsiniz.

İzleme ve özel projeksiyonlar

Sorgunun sonuç türü bir varlık türü olmasa bile, EF Core varsayılan olarak sonuçta yer alan varlık türlerini izlemeye devam eder. Anonim bir tür döndüren aşağıdaki sorguda, sonuç kümesindeki örnekleri Blog izlenir.

var blog = context.Blogs
    .Select(
        b =>
            new { Blog = b, PostCount = b.Posts.Count() });

Sonuç kümesi LINQ bileşiminden 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ıktaki değerlerden bazılarını içeren anonim bir tür döndüreceğiz (ancak gerçek varlık türünün örneği yok). Sorgudan çıkan izlenen varlık yok.

var blog = context.Blogs
    .Select(
        b =>
            new { Id = b.BlogId, b.Url });

EF Core, en üst düzey projeksiyonda istemci değerlendirmesi yapmayı destekler. EF Core, istemci değerlendirmesi için bir varlık örneğini oluşturursa izlenir. Burada, varlıkları istemci yöntemine StandardizeURLaktardığımız blog için EF Core blog örneklerini de izler.

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 varlık türlerinin diğer tüm örneklerini izler.

Önceki sürümler

3.0 sürümünden önce EF Core izlemenin nasıl yapıldığı konusunda bazı farklılıklara sahipti. Önemli farklar şunlardır:

  • İstemci ve Sunucu Değerlendirmesi sayfasında açıklandığı gibi EF Core, 3.0 sürümünden önceki sorgunun herhangi bir bölümünde istemci değerlendirmesini destekledi. İstemci değerlendirmesi, sonucun parçası olmayan varlıkların gerçekleştirilmesine neden oldu. Bu nedenle EF Core, neyin izlenmiş olduğunu algılamak için sonucu analiz etti. Bu tasarımın aşağıdaki gibi bazı farklılıkları vardı:

    • Yansıtmadaki istemci değerlendirmesi, gerçekleştirmeye neden oldu ancak gerçekleştirilmiş varlık örneğini döndürmedi izlenmedi. Aşağıdaki örnek varlıkları izlemedi blog .

      var blogs = context.Blogs
          .OrderByDescending(blog => blog.Rating)
          .Select(
              blog => new { Id = blog.BlogId, Url = StandardizeUrl(blog) })
          .ToList();
      
    • EF Core, belirli durumlarda LINQ bileşiminden çıkan nesneleri izlemedi. Aşağıdaki örnek izlemedi 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, sorgunun tamamı izlenmez hale getirildi. Bu, sonuçtaki anahtarlara sahip varlık türlerinin de izlenmediği anlamına gelir.

  • EF Core, izlemesiz sorgularda kimlik çözümlemesi yapmak için kullanılır. Daha önce döndürülmüş varlıkları izlemek için zayıf başvurular kullandı. Bu nedenle, bir sonuç kümesi aynı varlığı birden çok kez içeriyorsa, her oluşum için aynı örneği alırsınız. Aynı kimliğe sahip önceki bir sonuç kapsam dışına çıksa ve çöp toplandıysa, EF Core yeni bir örnek döndürdü.