C# — Lambda expressionlar ile LINQ sorguları
Merhaba arkadaşlar,
Bu yazımda C#’ta sık sık kullandığımız lambda expression kullanarak LINQ ile query ifadeleri yazmak üzerine bir derleme yapıyor olacağım. Amacım kendim için güzel bir pratik ve lambda ile sorgu yazmakta yeni olan arkadaşlara bir rehber olmasıdır. Umarım okuyanlar için faydalı bir yazı olur. 🙏
Planladığımın aksine baya 101 yazısı oldu. Umarım bu yazının ikincisinde kompleks LINQ sorgularını irdelerim. 😅
LINQ(Language Integrated Query) collectionlar’a c# üzerinde data source (ADO.NET, XML Doc, Collection) bağımsız olarak query yazmamıza yarayan teknoloji kümesidir. LINQ bize query yazarken kullanabileceğimiz 2 seçenek sunar. SQL-Like sorgulama (Query expression)ve method like sorgulama (Lambda) Ben yazının girişinde bahsettiğim gibi lambda kullanarak sorgularımı yazağım.
Yazı içerisinde kullandığım örnekleri github linkinde bulabilirsiniz. Anlaşılmayan bölümlerde ilgili methodun testini debug edebilirsiniz.
Bahsedeceğim LINQ query (LINQ to Objects) konuları aşağıdadır.
- Aggregation (Average, Max, Min, Sum)
- Conversion (OfType, ToDictionary, ToLookup)
- Element (First, FirtOrDefault, Last, LastOrDefault, Single, SingleOrDefault)
- Grouping (GroupBy)
- Join (Join, GroupJoin)
- Ordering (OrderBy, OrderByDescending, Reverse, ThenBy, ThenByDescending)
- Partitioning (Skip, SkipWhile, Take, TakeWhile)
- Projection (Select, SelectMany)
- Quantifiers (All, Any, Contains)
- Restriction (Where)
- Set (Distinct, Except, Intersect, Union)
Aggregation
Average
Sayı kumesinin ortalama değerini bulan extension methodtur.
Max
Sayı kumesindeki en büyük değeri bulan extension methodtur.
Min
Sayı kumesindeki en küçük değeri bulan extension methodtur.
Sum
Sayı kumesindeki elemanların toplamını bulan extension methodtur.
Aggregation çok sıklıkla kullanılan giriş elemanları olduğu için her birinin altına ilgili kodları eklemedim. Ancak arzu ederseniz github üzerinden aggregationlar ve diğer tüm konular hakkında yazılmış kodlara göz atabilir.
Conversion
OfType
Elemanlar arasından belirtilen type’a göre filtreleme yapar.
Örnekteki kullanımda OfType<string> sayesinde yalnızca “Kartal” ifadesinin result’a döndüğünü görmekteyiz. Çok kullanılmayan ama gayet işlevsel bir extension OfType
ToDictionary
Collection’u Dictionary’e çeviren extensiondur.
Örneğimizde Id’si 2 den büyük olan ürünleri “New” value değeriyle <product, string> dictionary’mize attık. Ürünlerimizin sırasıyla int Id değerlerini aldığını göz önünde bulundurursak 2'den büyük 3 ürünümüzün olduğunu anlayabiliriz. Testimizdeki assertion buna göre yapılmıştır.
ToLookup
Collection’u key bazlı gruplayan extensiondur.
Örneğimizdeki 5 ürünümüzü bogus generator ile oluştururken, productId’leri 2'ye bölünebilenleri football bölünemeyenleri basketboll kategorisine atadım.
.RuleFor(p => p.Category, f => productId % 2 == 0 ? "Football" : "Basketball");
Conversion ToLookup methodumdan yalnica football keyiyle olanlari döndürdüm.
Sonuç 🕶
Element
Element extensionlarıda aslında günlük hayatta sıklıkla kullandığımız extensionlar. First ve Single metodlarının kullanımıyla ilgili hafta sonu okuduğum bir makele buradan paylaşmak istiyorum.
Elementlerle ilgili örnekleride github üzerinden görebilirsiniz. Kullanımı çok yaygın olduğu için kod paylaşımını yazı üzerinden yapmayacağım.
First
Collectiondaki ilk elemanı bulan extension methodtur. Eğer collectionda aranan değer bulunamadıysa InvalidOperationException fırlatır.
FirstOrDefault
Collectiondaki ilk elemanı bulur, eğer eleman yoksa type’in default value’sini döndürür.
Last
Collectiondaki son elemanı bulan extension methodtur. Eğer collectionda aranan değer bulunamadıysa InvalidOperationException fırlatır.
LastOrDefault
Collectiondaki son elemanı bulur, eğer eleman yoksa type’in default value’sini döndürür.
Single
Collectionda yer alan tek bir uniqe elemanı bulan extension methodtur. Eğer collectionda aranan eleman bulunamadıysa veya birden daha fazla sayıda varsa InvalidOperationException fırlatır.
SingleOrDefault
Collectionda yer alan tek bir uniqe elemanı bulan extension methodtur. Eğer eleman bulunamdıysa diğer OrDefault’lar gibi default valueyi döner. Aranan eleman collectionda yoksa InvalidOperationException fırlatır.
Grouping
GroupBy
Adındanda anlaşılacağı gibi Collection içerisindeki elemanları bir değer bir keySelector vasıtasıyla gruplamaya yarar.
Aşağıdaki örnekte Category’si “Football” olan elemanlar gruplanmıştır. IEnumerable<IGrouping<bool, Product>> üzerinden grupta olanlar Where key == true ile ayrılarak değişkene atanmıştır.
Join
GroupJoin (Left Outer Join)
Birbirleriyle key ilişkisi olan 2 ayrı collectioniu birbirine bağlamaya yarar. Örneğimizdeki Product ve Variant modellerini birbirlerine productId yardımıyla bağlacağız.
Product modelindeki Id’yi işaret eden Variantları oluşturduğumuz yeni Product listemize ekliyoruz.
Farkı daha iyi görebilmek için Test anında Product’i oluşturduğumuzda Variants null’dur ancak join işlemimizden varianlarda productId’si eşleşen değerler yeni modelimizde Product’ının variantında dönmektedir.
Join (Inner Join)
Join 2 ayrı collection’u belirtilen key göre bir collection haline getirir.
Aşağıdaki örnekte inner joinimizden sonra elimizde olan collectionumızda yalnıca “A” string değeri bulunmaktadır.
Ordering
OrderBy
Collection’u küçükten büyüğe sıralar.
OrderByDescending
Collection’u büyükten küçüğe sıralar.
Reverse
Collection’daki elemanların ters çevirir.
a -> b -> c = (reverse) = c -> b -> a
ThenBy
Sıralamadan sonra sırlanan değerleri 2. bir key’e göre küçükten büyüğe sıralama işlemi yapılmasını sağlayan methodtur.
ThenByDescending
Sıralamadan sonra sırlanan değerleri 2. bir key’e göre büyükten küçüğe sıralama işlemi yapılmasını sağlayan methodtur.
Partitioning
Skip
Parametre olarak belirtilen değere kadar olan elemanı atlamaya yarayan methodtur.
string[] numbers = {"one", "two", "three"};
var result = numbers.Skip(1);
// result is now = {"two", "three"}
SkipWhile
Şartlı atlama işlemi yapan methodtur. Örneğin aşağıdaki işlemimiz length’i 3 olan elemanları atlattık.
Take
Baştan belirtlen sayıya kadar elemanı alanlardan oluşan collection yaratan method.
Projection
Select
Elemanları bir collection’a dönüştürmize yarayan extension methodtur.
SelectMany (Cross Join)
Basitçe anlatmak gerekirse collection içerisindeki collectionları düz bir liste biçiminde bize veren extensiondur.
Örnek verecek olursak. Product objemiz variantlar içermektedir. Bu variantları direk bir collection olarak elde etmemize yarar yani işlem sonucunca IEnumerable<Variant> sonucunu elde etmemiz gibi.
Quantifiers
All
Collection içerisindeki her elemanın verilen önermeyi sağlamasını kontrol eder.
Aşağıdaki örnekte eğer tüm productların pricelar’ı 0'dan büyükse sonucu true dönmektedir.
return products.All(p => p.Price > 0m);
Any
Collection içerisindeki herhangi bir elemanın verilen önermeyi sağlamasını kontrol eder.
Aşağıdaki örnek için productlarımız içerisinden bir tane ürünün pricesi 0'dan büyükse sonuç true olarak dönmektedir.
return products.Any(p => p.Price > 0m);
Contains
Collection içerisindeki herhangi bir elemanın verilen contains içeriğini sağlamasını kontrol eder.
return products.Select(p => p.Name).Contains("A");
Restriction
Where
Collection içerisindeki elemanları filtrelemeye yarayan ifadedir.
Fiyat’ı 0'dan büyük productlar için filtreleme yapan linq sorgusu
return products.Where(p => p.Price > 0m);
Set
Distinct
Duplicate elemanları silen extensiondur.
Except
Karşılaştırıldığı collectionda tekrarlayan elemanları eleyen methodtur.
Intersect
Except’in tam tersi olarak yalnızca tekrarlamayan elemanlari eleyen methodtur. Yani yalnızca paylaşılan elemanları döner.
Union
Karşılaştırılan objeleri birleştirip distinct yapan extension methodtur.
Çok uzun bir makale oldu. Bazı bölümleride çok basic kaldı :) İstatistiklerde kaç okunma göreceğim çok merak ediyorum.😁