Date Image Tuesday, December 22, 2009 | Kategoriler | Entity Framework, Tümü

Entity Framework'te Lazy Loading Tasarım Kalıbının Önemi

   Yazılım projelerinde sıkça kullanılan bir tasarım kalıbı olan Lazy Loading yani nesnelerin gerektiği zaman instance ının alınması ya da kullanılması, entity framework'te performans açısından oldukça fark etmektedir. Aklıma ilk gelen şey; northwind veritabanındaki category tablosundan kategorileri çağırıp relational tablosu olan products tablosundan da verileri çekecek mi? Bunu aklıma getiren şey, ORM yapısında olan ilişkli tabloların yine ilişkli bir şekilde class yapısına dönüştürüldüğünde products ın categories altında bir koleksiyon olarak bulunacak olması. Kafanız karışmış olabilir diye düşünerek hemen örneğe geçiyorum. Lazy Loading i .Net Framework 4.0 Beta 2, VS 2010 Beta 2 ile inceliyorum..

static void Main(string[] args)

        {

            using (NorthwindEntities db = new NorthwindEntities())

            {

                List<Categories> categories = db.Categories.OrderBy(c => c.CategoryName).ToList();

 

                foreach (Categories cat in categories)

                {

                    Console.WriteLine(string.Format("{0} [{1}]",

                                               cat.CategoryName,

                                               cat.Products.Count));

                    WriteProducts(cat);

                }

            }

        }

        static void WriteProducts(Categories category)

        {

            foreach (Products prod in category.Products)

            {

                Console.WriteLine(string.Format("\t{0}",prod.ProductName));

            }

        }

 

Entity Framework Lazy Loading 1

 

   Örneğimizde tüm kategorileri adına göre sıralayarak bir list oluşturuyoruz. Artık elimizde tüm kategoriler olduğuna göre products tablosundan da verileri getirip getirmediğini deneyebiliriz. foreach ile her bir kategorideyken altındaki product ları almaya çalıştım. WriteProducts metodunu oluşturup parametre olarak categories olarak her bir dönüşte category yi gönderip altındaki productları console a yazdırdım.

   Sql Profiler dan arkaplanda çalıştırılan sql sorgularını incelediğimde foreach döngüsüne gelene ve product lar çekilmek istenene kadar sadece tüm kategorileri getiren bir sorgu çalıştırıldığını gördüm.

Ne zamanki ürünler isteniyor ozaman products koleksiyonu dolduruluyor.

 

SELECT
[Extent1].[CategoryID] AS [CategoryID],
[Extent1].[CategoryName] AS [CategoryName],
[Extent1].[Description] AS [Description],
[Extent1].[Picture] AS [Picture]
FROM [dbo].[Categories] AS [Extent1]
ORDER BY [Extent1].[CategoryName] ASC
 
 

   Şimdi de Lazy Loading i kapatalım.

 

static void Main(string[] args)

        {

            using (NorthwindEntities db = new NorthwindEntities())

            {

                db.ContextOptions.LazyLoadingEnabled = false;

 

                List<Categories> categories = db.Categories.OrderBy(c => c.CategoryName).ToList();

 

                foreach (Categories cat in categories)

                {

                    Console.WriteLine(string.Format("{0} [{1}]",

                                                    cat.CategoryName,

                                                    cat.Products.Count));

                    WriteProducts(cat);

                }

            }

        }

        static void WriteProducts(Categories category)

        {

            foreach (Products prod in category.Products)

            {

                Console.WriteLine(string.Format("\t{0}",prod.ProductName));

            }

        }

 

   Entity modelimizin ContextOptions.LazyLoadingEnabled özelliğini false olarak set ettik. ContextOptions.LazyLoadingEnabled ne için kullanılıyormuş bir bakalım.

 

Entity Framework Lazy Loading 2

 

  Örneğimze göre açıklarsak; category altındaki products ın bir property si çağırılırsa otomatik olarak   yüklenecektir. Yani product çağrılmazsa veritabanına erişim olmayacak. Performans artışı sağlanacak. Ancak örneğimizde productlar listelenmeyecektir.

 

Entity Framework Lazy Loading 3

 

Görüldüğü gibi Lazy Loading kapatıldığı için Products istekte bulunduğumuzda otomatik olarak yüklenmedi.

  

   Lazy Loading kapatıldığında da yükleyebiliyoruz eğer istersek. Nasıl olduğuna bakalım.

 

   categories içerisinde dönerken;

  

cat.Products.Load();

 eklersek o anki categorinin product larını yüklemiş olacağız.

 

Ya da

 

List<Categories> categories = db.Categories.Include("Products").OrderBy(c => c.CategoryName).ToList();

ile kategorileri alırsak, ürünleri de yüklemiş olacağız. Bu şekilde kullandığımızda arkaplanda sadece bir sorgu çalıştırılacaktır.

Load ile yüklediğimizde ise her seferinde bir sorgu çalıştırılacak ve 8 kategori için 8 sorgu çalıştırılacaktır.

 

Burada tercih bize kalıyor, eğer tüm kategori ve ürünleri göstermeyeceksek, belirli kategorilerin ürünlerini göstereceksek Load kullanmak daha mantıklı gibi.

Bundan sonrası sizin elinizde..

Etiketler :