Derinlemesine yazılım eğitimleri için kanalımı takip edebilirsiniz...

Entity Framework Core – Lazy Loading

Merhaba,

Yazılım uygulamalarında temelde esas amacımız bir veriyi doğru işleyebilmek ve varsa üretilen çıktıyı doğru bir şekilde gerekli yere yansıtabilmektir. Basit bir rehberlik uygulamasından tutun uzaya füze göndermeye kalksak bile en temeldeki gayemiz budur ve tüm çaba ve inşalarımız bunun üzerine kuruludur. Keza veri dediğimiz olgu tek başına büyük anlam ifade etsede, birden fazla veri ilişkisel olarak bir araya gelerek oluşturdukları bütün sayesinde daha da büyük anlam ifade edebilmektedirler. Dolayısıyla yazılım uygulamaları genellikle tek bir veri üzerinden değil, o veriyle ilişkili diğer veriler üzerinden de işlem yapma mecburiyetini gütmektedirler. Haliyle süreçte elimizde olan veriyle ilişkili tüm verileri elde etmemiz gerekebilir. İşte bunun için elimizdeki veriyle ilişkisel olan tüm verileri tek tek getirmek yerine Entity Framework bu işi üstlenmekte ve Lazy Loading dediğimiz Tembel Yükleme aracılığıyla ilgili verileri bizlere ulaştırmaktadır.

.NET Core’dan önce Standart Framework mimarisinde Entity Framework yapılanması varsayılan olarak açık bir şekilde gelmekteydi. Keza bu varsayım en basit sorgularda bile lüzumsuz ilişkisel tüm verileri getirmekte ve hem sorgusal hem de yazılımsal yüksek maliyetlere sebep olmaktaydı. Bu duruma istinaden biz developerlar varsayılan Lazy Loading mekanizmasını kapatır ve ihtiyacımız doğrultusunda Include mekanizmasını devreye sokardık.

.NET Core mimarisi buradaki varsayımsal durumu değiştirerek Entity Framework Core yapılanmasında Lazy Loading mekanizmasını kapatarak, ihtiyaç dahilinde developerın iradesine bırakmıştır ve böylece Lazy Loading mekanizmasını bilmeyenler için yersiz maliyetin önüne geçmiştir. İşte bu içeriğimizde Entity Framework Core çalışmalarında Lazy Loading’i nasıl devreye sokacağımızı ve nelere dikkat etmemiz gerektiğini inceleyeceğiz.

İlk Olarak

Herşeyden önce örneklendirme yapabilmek için bir adet Asp.NET Core MVC uygulaması açınız ve ardından ister Code First istersenizde Database First yöntemiyle uygulamayı bir veritabanı ile ilişkilendiriniz.

Ayrıca…

Lazy Loading; Entity Framework Core kütüphanesine dahili olarak eklenmemiş, harici olarak Proxy şeklinde kullanılabilir bir özelliğe çevrilmiştir. Bundan dolayı .NET Core – EF Core uygulamalarında Lazy Loading’i kullanabilmek için Microsoft.EntityFrameworkCore.Proxies kütüphanesini projeye entegre etmeniz gerekmektedir.

Lazy Loading Proxy Kullanımı

EF Core uygulamasında Lazy Loading Proxy’i devreye sokabilmek için context sınıfı(DbContext’ten türeyen) içerisinde override edilen “OnConfiguring” metodunda aşağıdaki operasyonun gerçekleştirilmesi gerekmektedir.

    public class MyDBContext : DbContext
    {
        public MyDBContext(DbContextOptions<MyDBContext> dbContext) : base(dbContext) { }
        public DbSet<Personel> Personeller { get; set; }
        public DbSet<Satis> Satislar { get; set; }

        protected override void OnConfiguring(DbContextOptionsBuilder optionsBuilder)
        {
            optionsBuilder.UseLazyLoadingProxies();
        }
    }

Bu işlem neticesinde artık ilgili uygulamada yapılan tüm EF sorgulamalarında Lazy Loading çalışacak ve hedeflenen veriler ilişkisel olduğu veriler ile bütün halinde elde edilecektir.
Entity Framework Core - Lazy Loading

Olası InvalidOperationException Hatası

Yukarıdaki çalışmayı yaptığınız taktirde InvalidOperationException olası hatasını alıyorsanız aşağıdaki durumları göz önüne alarak çalışmanızı düzenlemenizi öneririm. Tabi öncelikle ilgili hatayı tam olarak incelememiz gerekirse eğer;

System.InvalidOperationException: ‘Navigation property ‘Satislar’ on entity type ‘Personel’ is not virtual. UseLazyLoadingProxies requires all entity types to be public, unsealed, have virtual navigation properties, and have a public or protected constructor.’

Hatanın görsel hali ise;
Entity Framework Core - Lazy Loading

Çözüm
Bu hatanın sebebi, Lazy Loading yapılırken entityler/modeller arasındaki ilişkiyi sağlayan Navigation Propertylerin sanal olarak tanımlanmamasından kaynaklanmaktadır. Yapmamız gereken tek işlem tüm modellerdeki ilişkisel bağları oluşturan propertyleri virtual keywordü ile işaretlemenizdir.
Entity Framework Core - Lazy Loading
İşte çözüm bu kadar basit 🙂

Ve böylece .NET Core uygulamalarında EF Core ile Lazy Loading’in nasıl yapılacağını detaylıca incelemiş ve olası hatalara dair nasıl çözüm alınabileceğini görmüş olduk. Tabi siz yine ehemmiyeti göz ardı etmeksizin lüzum olmadığı taktirde Lazy Loading mekanizmasını mümkün mertebe pasif tutmaya özen göstermeyi unutmayınız 🙂

İlgilenenlerin faydalanması dileğiyle…
Sonraki yazılarımda görüşmek üzere…
İyi çalışmalar…

Bunlar da hoşunuza gidebilir...

7 Cevaplar

  1. Hasan Eren dedi ki:

    Merhaba, dediklerinizi adım adım yaptım ama maalesef resimde gördüğünüz hatayı aldık bunun sebebi nedir? https://www.hizliresim.com/6e1zwf6

  2. Ahmet Sökmen dedi ki:

    Hocam merhabalar. Değerli emekleriniz için size çok teşekkür ederim. Sizden çok şey öğreniyorum. Yalnız bu makale ile birkaç blogu mukayese edince ciddi bir farklılık durumu olduğunu görüyorum. Lazy loading yöntemi hakkında ya sizin söyledikleriniz yanlış yahut yabancı forumlarda konuşulanlar yanlış gibi geliyor kanaatimce :

    Şöyle ki lazy loadingde sizin anlatımınızda bir entitye ait tüm ilişkili entityler birlikte anında yükleniyor gibi anladım ben. Halbuki sql server profilerden de teyit ettiğim üzere böyle bir durum yok. Yalnızca siz ilişkili entityi call edince ilişkili entityler yükleniyor. Örnekteki fotoğrafta da runtime esnasında navigation propertyye tıkladığınız an aslında lazy loading ile veritabanına yeni bir sorgu gönderiyorsunuz ilişkili entityde çağırmak için. Yani baştan her şeyi yüklemek gibi bir durum yerine siz tıklayınca veya person.persondetails şeklinde get etmeye çalışınca anında veritabanına yeni bir sorgu gidiyor ve bunu ef lazy loading sayesinde otomatik yapıyor.

    Yanlış anladıysam affola. Rica etsem siz de sql profiler kullanarak bu dediğim hususa göz atabilir misiniz.

    Saygılar.

    • Gençay dedi ki:

      Merhaba,

      Doğrusu yorumunuza katılıyorum. Lakin içerikte dediğiniz hataya dair paragrafın nerede olduğuna dair okumaya vaktim olmadığı için varsa öyle bir yanlış tabi ki de sizin dediğiniz mantıkla ilgili noktaların düzeltilmesi gerektiği kanaatindeyim.

      Teşekkürler.
      Sevgiler.

      • Ahmet dedi ki:

        İlginiz için çok teşekkür ederim.

        Gönderideki ikinci fotoğraf ve hemen öncesindeki küçük paragrafta sanki her şey baştan bir bütün olarak geliyor gibi anladım. Belki ben de yanlış anlamış olabilirim.

        Çalışmalarınızda başarılar dilerim.
        Sevgiler.

  1. 01 Kasım 2019

    […] eğer ki birbiriyle ilişkisel verilerden ibaretse(ki genellikle bu şekilde ilişkisel veriler Entity Framework Core – Lazy Loading mekanizması ile elde edilir) bu parse işlemi gerçekleştirilemeyecek ve makalemizin […]

  2. 09 Haziran 2021

Bir cevap yazın

E-posta hesabınız yayımlanmayacak. Gerekli alanlar * ile işaretlenmişlerdir