Geçtiğimiz günlerde gerçekleştirdiğim Veritabanı Yerine Cache’deki Verilerle Çalışmak webinerine yapılan katılımdan ve webiner sonrasında mail yoluyla takipçilerimle yaptığım konuşmalardan oldukça memnunum. Birçok kişiye yol göstermek ve birlikte güzel beyin fırtınaları yapmak oldukça keyifli oluyor. Webinerde bütün basit LINQ ifadeleri ile aldığımız sorgu sonuçlarını Entity Framework’te generic metotlarda nasıl cacheleyebileceğimizi incelemiştik. Kompleks sorgular için kullanılacak metodu da blogumda yayınlayacağımı belirtmiştim, işte ilgili kodlar aşağıda yer almakta.
Karmaşık sorgularda generic bir yapı oluşturabilmek için Cache’de tutacağımız key değerini ancak sorgunun t-sql ifadesine dönüşmüş halini kullanarak sağlıklı şekilde yapabiliriz. Bu nedenle ToTraceString() metodu aracılığıyla elimizdeki LINQ ifadesini t-sql ifadesine dönüştürmemiz ve Cache’e atılacak nesnenin key değerini t-sql ifadesi olarak kullanmamız gerekiyor. Aşağıdaki extension metot tüm LINQ sorgularında kullanılabilir.
public static class IQueryableExtension { public static List<T> GetCache<T>(this IQueryable<T> query) { string sql = ((ObjectQuery)query).ToTraceString(); if (HttpContext.Current.Cache[sql] == null) { List<T> list = query.ToList(); HttpContext.Current.Cache.Insert(sql, list); } return HttpContext.Current.Cache[sql] as List<T>; } }
Örnek kullanım şekilleri ise şöyle:
using (NorthwindEntities context = new NorthwindEntities()) { var result = context.Products.Join(context.Categories, p => p.CategoryID, c => c.CategoryID, (p, c) => new { Products = p, Categories = c }).GetCache(); var result2 = context.Products.GetCache(); var result3 = (from p in context.Products where p.CategoryID == 2 select p).GetCache(); }