Verimli Güncelleştirme

İşlem grubu oluşturma

EF Core, tüm güncelleştirmeleri tek bir gidiş dönüşte otomatik olarak toplu işleyerek gidiş dönüşleri en aza indirmeye yardımcı olur. Aşağıdakileri göz önünde bulundurun:

var blog = context.Blogs.Single(b => b.Url == "http://someblog.microsoft.com");
blog.Url = "http://someotherblog.microsoft.com";
context.Add(new Blog { Url = "http://newblog1.microsoft.com" });
context.Add(new Blog { Url = "http://newblog2.microsoft.com" });
context.SaveChanges();

Yukarıdaki, veritabanından bir blog yükler, URL'sini değiştirir ve ardından iki yeni blog ekler; bunu uygulamak için veritabanına iki SQL INSERT deyimi ve bir UPDATE deyimi gönderilir. Blog örnekleri eklendikçe, EF Core bunları tek tek göndermek yerine bu değişiklikleri dahili olarak izler ve çağrıldığında SaveChanges tek bir gidiş dönüşte yürütür.

EF'nin tek bir gidiş dönüşte toplu iş yaptığı deyimlerin sayısı, kullanılan veritabanı sağlayıcısına bağlıdır. Örneğin performans analizi, 4'ten az deyim söz konusu olduğunda toplu işlemlerin SQL Server için genel olarak daha az verimli olduğunu göstermiştir. Benzer şekilde, SQL Server için yaklaşık 40 deyimden sonra toplu işlemlerin avantajları azalır, bu nedenle EF Core varsayılan olarak tek bir toplu işlemde en fazla 42 deyim yürütür ve ayrı gidiş dönüşlerde ek deyimler yürütür.

Kullanıcılar ayrıca, potansiyel olarak daha yüksek performans elde etmek için bu eşikleri değiştirebilir, ancak bunları değiştirmeden önce dikkatli bir şekilde karşılaştırma yapabilir:

protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
{
    optionsBuilder.UseSqlServer(
        @"Server=(localdb)\mssqllocaldb;Database=Blogging;Trusted_Connection=True",
        o => o
            .MinBatchSize(1)
            .MaxBatchSize(100));
}

Uygun olduğunda ExecuteUpdate ve ExecuteDelete kullanma

Tüm çalışanlarınıza zam yapmak istediğinizi varsayalım. EF Core'da bunun tipik bir uygulaması aşağıdaki gibi görünür:

foreach (var employee in context.Employees)
{
    employee.Salary += 1000;
}
context.SaveChanges();

Bu tamamen geçerli bir kod olsa da performans açısından ne yaptığını analiz edelim:

  • Tüm ilgili çalışanları yüklemek için bir veritabanı gidiş dönüş gerçekleştirilir; Bunun, yalnızca maaş gerekse bile tüm Çalışanların satır verilerini müşteriye getirdiğini unutmayın.
  • EF Core'un değişiklik izlemesi, varlıkları yüklerken anlık görüntüler oluşturur ve ardından hangi özelliklerin değiştiğini bulmak için bu anlık görüntüleri örneklerle karşılaştırır.
  • Genellikle, tüm değişiklikleri kaydetmek için ikinci bir veritabanı gidiş dönüş gerçekleştirilir (bazı veritabanı sağlayıcılarının değişiklikleri katlar gidiş dönüşlerine böldüğüne dikkat edin). Bu toplu işlem davranışı her güncelleştirme için gidiş dönüş yapmaktan çok daha iyi olsa da, EF Core yine de çalışan başına bir UPDATE deyimi gönderir ve veritabanının her deyimi ayrı olarak yürütmesi gerekir.

EF Core 7.0'dan başlayarak ve ExecuteDelete yöntemlerini kullanarak ExecuteUpdate aynı şeyi çok daha verimli bir şekilde yapabilirsiniz:

context.Employees.ExecuteUpdate(s => s.SetProperty(e => e.Salary, e => e.Salary + 1000));

Bu, veritabanına aşağıdaki SQL deyimini gönderir:

UPDATE [Employees] SET [Salary] = [Salary] + 1000;

Bu UPDATE işlem, tüm işlemi veritabanına herhangi bir gerçek veri yüklemeden veya göndermeden ve EF'nin ek yük oluşturan değişiklik izleme makinelerinden yararlanmadan tek bir gidiş dönüşte gerçekleştirir. Daha fazla bilgi için bkz. ExecuteUpdate ve ExecuteDelete.

EF Core'un henüz ve ExecuteDelete'yi desteklemeyen ExecuteUpdate eski bir sürümünü kullanıyorsanız veya bu yöntemler tarafından desteklenmeyen karmaşık bir SQL deyimi yürütmek istiyorsanız, işlemi gerçekleştirmek için bir SQL sorgusu kullanmaya devam edebilirsiniz:

context.Database.ExecuteSql($"UPDATE [Employees] SET [Salary] = [Salary] + 1000");

ile/ExecuteDeleteExecuteUpdate arasındaki SaveChanges farklar hakkında daha fazla bilgi edinmek için verileri kaydetmeye ilişkin Genel Bakış sayfasına bakın.