C# — Lambda expressionlar ile LINQ sorguları

Aybars Arslan
SDTR
Published in
5 min readNov 9, 2020
Photo by Andrew Neel on Unsplash

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.😁

Photo by Luis Villasmil on Unsplash

References

--

--

Aybars Arslan
SDTR
Writer for

Basically C# .NET Developer but always looking for new things to improve software development life cycle 🚀