LINQ sorguları kolleksiyon temelli yapılarda sorgulamalar ve seçimler yapmak için bize imkan sağlar. Döngülerle diziler içerisinde boğuşmadan istediğimiz formatta sonuç almamıza yardımcı olurlar.
Bazen ihtiyaçlarımız doğrultusunda bir tipte oluşturulmuş kolleksiyon içerisinden başka bir tipte seçimler yapmak durumunda kalabiliriz. Bu noktada kurtarıcı olarak yine LINQ sorgularından faydalanabilmekteyiz.
Örneğin bir ürüne ait bilgileri tutan “Product” tipine ait kolleksiyon içerisinden bize lazım olan ürün başlıklarını seçip alacağımız “ProductTitle” tipli kolleksiyon oluşturma gereği duyduğumuz bir senaryo düşünebiliriz. Bu durumda tüm “Product” nesnesini taşımak yerine ürün adlarını barındıran “ProductTitle” adlı tipi tercih etmiş oluyoruz. Bu şekildeki bir seçimi yapmak için şu şekilde bir LINQ sorgusu yazabiliriz.
var productTitles = db.Products.Select(p => new ProductTitle{
Id = p.Id,
Name = p.Name
});
Ancak bazı durumlarda seçim yaptığımız tip özellikleri, Property ataması ile değil de bir kurucu metod (Constructor) ile tipe enjekte edileceği durumu senaryo edecek olursak nasıl bir durumla karşılaşacağımıza bakalım.
StoreEntities db = new StoreEntities();
var productTitles = db.Products.Select(p => new ProductTitle(p));
Yukarıdaki sorguyu, eğer bir Entity Framework modeli üzerinde çalıştıracak olursak karşımıza şu şekilde bir hata mesajı çıkacaktır.
Unhandled Exception: System.NotSupportedException: Only parameterless constructors and initializers are supported in LINQ to Entities.
LINQ provider, ProductTitles tipinini kurucu metodunda nasıl bir kodun çalıştırılacağından habersizdir. Entity Framework ise LINQ sorgularını olduğu gibi T-SQL sorgularına dönüştürmeye çalışır. Fakat sorgu içerisindeki bir tipin(ProductTitle) kurucu metodunda neler olup bittiğini bilmediğinden işlem durdurulur ve hata raporu oluşturulur.
Bu durumun çözüm yolu ise Entity Framework tarafından IQueryable olarak sunulan kolleksiyonu AsEnumerable extension metodu yardımıyla IEnumerable olarak değiştirmektir.
StoreEntities db = new StoreEntities();
var productTitles = db.Products
.AsEnumerable()
.Select(p => new ProductTitle(p));
Burada sorguda AsEnumerable() extension metodu önce veriyi çekiyor. Ardından seçilen kolleksiyon içerisinden seçim işlemi yapılıyor. Bu sayede hata giderilmiş oluyor. Entity Framework sorgularının IQueryable ve IEnumerable karşısındaki davranışları ve T-SQL dönüşümünü incelemek için Burak Selim Şenyurt’un buradaki ipucundan faydalanabilirsiniz.
Bir sonraki yazıda görüşmek dileğiyle.