Makale Özeti

Bu yazı dizimizde Linq ile çeşitli sorgular çalıştıracak ve Linq'un nimetlerini göz önüne sereceğiz. Linq nedir ? gibi sorulara yer vermeyeceğiz çünkü daha önce diğer arkadaşlarım çeşitli açıklama ve yorumlarla bu sorulara detaylı olarak yanıt verdiler. Bilmeyenler için aşağıdaki linkleri incelemeleri rica olunur.

Makale

Merhaba Arkadaşlar;

Bu yazı dizimizde Linq ile çeşitli sorgular çalıştıracak ve Linq'un nimetlerini göz önüne sereceğiz. Linq nedir ? gibi sorulara yer vermeyeceğiz çünkü daha önce diğer arkadaşlarım çeşitli açıklama ve yorumlarla bu sorulara detaylı olarak yanıt verdiler. Bilmeyenler için aşağıdaki linkleri incelemeleri rica olunur :)

Linq İle Daha Fazla Sorgu
LINQ: Language Integrated Query - 1
LINQ: Language Integrated Query - 2

Şimdide küçük bir alıştırma ile ısınalım. Bildiğiniz gibi Linq ile diziler veya objeler içerisinde sorulama yapabiliryoruz. İlk önce bir dizi içerisinde sorgulama ile başlayalım ve ilerledikçe sınırlarımızı zorlayalım. Bu arada unutmadan örneklerimizi tamamını web projesi üzerinden yapacağız. Örnekleri isteseniz sizler windows veya console uygulamalarında aynen çalıştırabilirsiniz. Makalenin sonunda benim kulladığım örneği sizlerle paylaşıyor olacağım. İlk olarak bir web projesi açalım ve başlayalım.

Proje Dosya Adı : Arrays.aspx

int[] numberArray = { 12, 10, 82, 115, 74, 0, 19,

                      34, 67, 12, 96, 44, 17, 63,

                      78, 56, 523, 1577, 458,111 };

 

var numbers = from n in numberArray select n;

 

foreach (var no in numbers)

{

    Response.Write(no + "<br />");

}

numberArray adındaki int[] dizi değişkenimizin içerisindeki tüm elemanları Linq sorgusu ile tip bağımsız bir değişkenimiz olan numbers a atadık. Tip bağımsız demek, eğer var ile tanımlanan numbers değişkeni ilk defa kullanılıyorsa atanan değer tipi ne olursa olsun kabul eder ve sonraki diğer kullanımlarda o tipe ait olur. Yani var ile tanımladığımız bir değişkene önce int sonra string bir değer atayamayız. Ayrıca bir nokta daha from n in numberArray olarak yazılan satırdaki n değişkeni sorgulanacak olan nesneyi temsil eder ve istediğiniz karekteri yazabilirsiniz. Yukarıdaki örneği biz normalde de foreach döngüsü ile yapıyorduk hemde var numbers... satırı olmadan dediğinizi duyar gibiyim. Evet doğru fakat 12'den büyük olanları listelemek isterseniz ne yapacaktınız ? Tabii ki if yazacaktınız döngü içerisine. Linq ile bunlara gerek yok. numberArray dizi değişkeninin 100'den büyük elemanlarını çeken sorgumuzda aşağıda :)

var numbers = from n in numberArray

                          where n > 100

                          select n;

 

            foreach (var no in numbers)

            {

                Response.Write(no + "<br />");

            }

Sonuç : 115, 523, 1577, 458, 111

Gördüğünüz gibi kolayca where kalıbı ile dizi değişkenimiz içerisinde 100'den büyük olan sayıları listeledik. Dizilerde nasıl sorgulama yaptığımızı gördükten sonra kendi yazdığımız veya List<T> koleksiyonundan faydalanarak oluşturduğumuz objelerin içerisinde nasıl sorgulama yapıyoruz ona bakalım. Aşağıda küçük bir class örneği oluşturdum.

Proje Dosya Adı : Category.cs

public class Category

   {

       public Category() { }

       public Category(int id, string name)

       {

           this.ID = id;

           this.Name = name;

       }

       public int ID { get; set; }

       public string Name { get; set; }

   }

Bundan sonraki örneklerde bu yapıyı aynen alıp kullanıyor olacağız. Şimdide nesneler üzerinden işlemler nasıl yapılıyor gösterelim.

Proje Dosya Adı : Objects.aspx

            List<Category> catList = new List<Category>();

            catList.Add(new Category(1, "Dizüstü Bilgisayarlar"));

            catList.Add(new Category(2, "El Bilgisayarları"));

            catList.Add(new Category(3, "Tablet Bilgisayarlar"));

            catList.Add(new Category(4, "Masaüstü Bilgisayarlar"));

            catList.Add(new Category(5, "Cep Telefonları"));

 

 

            var cat = from c in catList

                      where c.ID == 3

                      select c;

 

            foreach (var c in cat)

            {

                Response.Write(c.Name + "<br />");

            }

catList adında List<Category> koleksiyonumuzu oluşturduk ve List nesnesinin Add metodu ile elemanlarımızı tek tek içerisine ekledik. Sonra catList içerisinde ID si 3 e eşit olan tüm elemanları seçtik ve var cat değişkeni içerisine attık. Sonra da foreach ile ekrana yazdırdık. Aslında bu sorgunun çok daha kısa hali var. Nasıl mı ?

            var cat = catList.First(p => p.ID == 3);

            Response.Write(cat.Name);

Dikkat ederseniz buradaki sorgu türü biraz farklı p=> şeklinde bir ibare var. Nedir bu sorgu tipi peki ? Tabii ki Lambda Expression adını verdiğimiz bir syntax. Linq ile kullanıldığında muhteşem sonuçlar veriyor. Makalemizin konusu dışında olduğu için nedir ne değildir kısımlarını oluşturulmuş makalelere bırakıp biz linq ile kullanmayı anlatmayı tercih ediyoruz ;). p nereden geldi diye bir şey duydum sanki ?

p yerine siz a,b,c veya y de yazabilirdiniz. bu karakter o an sorgulanan objeyi temsil eder ve onun iözelliklerini listeler k=> bir kalıptır ve ayrılamaz. Mutlaka karakter => konulmak zorundadır. sonrada koşul belirtilir.

Sonuç olarak, Tablet Bilgisayarlar alıyor olmamız gerekiyor.

Küçük bir örnek daha. Kategori listesinden MasaÜstü ile başlayanların idlerini alalım.

var cat = from c in catList

          where c.Name.StartsWith("Masaüstü")

          select c.ID;

 

Response.Write(cat.First());

Sonuç : 4

Dikkatinizi çekmiş olmalı yazdırma işlemi sırasında cat.First() kullandık. First metodu o sorguya ait ilk elemanı geriye döndürür. Bende sorgumdan bir tane nesne döneceğini bildiğim için First kullandım. Eğer sorgumuzdan bir tane kayıt dönmeseydi For veya foreach ile dönüp duracaktık :)

Şimdi olayı biraz daha büyüterek ilişkisel nesne mantığı kurarak devam edelim ve Ürünler tablomuzuda ekleyelim. Bir kategorinin sonnuz ürünü olur mantığına uygun bir veri dizesi oluşturalım. Örnek class'ımız ve verilerimiz aşağıdadır.

Proje Dosya Adı : Product.cs

public class Product

{

    public Product() { }

    public Product(int id, int catID, string name, decimal price, int quan)

    {

        this.ID = id;

        this.CategorID = catID;

        this.Name = name;

        this.Price = price;

        this.Quantity = quan;

    }

 

    public int ID { get; set; }

    public int CategorID { get; set; }

    public string Name { get; set; }

    public decimal Price { get; set; }

    public int Quantity { get; set; }

 

}

Örnek DataListemiz

Proje Dosya Adı : SampleData.cs


public class SampleData

{

    public static Product[] GetProductData()

    {

        Product[] products = { new Product { ID = 1,

                                             CategorID = 1,

                                             Name = "HP DX2420 DUAL CORE E5200 2.5GHz 2GB 320GB MASAÜSTÜ BİLGİSAYAR VC553ES",

                                             Price = 499,

                                             Quantity = 2 },

                                new Product { ID = 2,

                                             CategorID = 1,

                                             Name = "CBOX BLAZER H700 CORE 2 DUO E7400 2.8GHz 2GB MASAÜSTÜ BİLGİSAYAR",

                                             Price = 55435,

                                             Quantity = 74 },

                                new Product { ID = 3,

                                             CategorID = 1,

                                             Name = "NOTEPAL AMD ATHLON 64 X2 5200+ 2.7GHz",

                                             Price = 105294,

                                             Quantity = 9741 },

                                new Product { ID = 4,

                                             CategorID = 2,

                                             Name = "NOKIA N82 ( 2 GB HAFIZA KARTI + 3 AYLIK NAVİGASYON PAKETİ HEDİYE )",

                                             Price = 55,

                                             Quantity = 87 },

                                new Product { ID = 5,

                                             CategorID = 2,

                                             Name = "NOKIA N66",

                                             Price = 905,

                                             Quantity = 10 }};

 

        return products;

    }

 

    public static Category[] GetCategoryData()

    {

        Category[] categories = { new Category { ID=1, Name="Bilgisayarlar"},

                                  new Category { ID=2, Name="Cep Telefonları"},

                                  new Category { ID=3, Name="Ofis Malzemeleri"},

                                  new Category { ID=4, Name="Kitaplar"},

                                  new Category { ID=5, Name="Mobilyalar"},

                                  new Category { ID=6, Name="Bahçe Malzemeleri"},

                                  new Category { ID=7, Name="Takı/Mücevher"},

                                  new Category { ID=8, Name="Bebek Malzemeleri"},

                                  new Category { ID=9, Name="Hobi Oyun"},

                                  new Category { ID=10, Name="Spor Malzemeleri"}

                                };

        return categories;

 

    }

}


Artık hem kategorilerimizin hemde ürünlerimizin dataları hazır. Bu aşamadan sonra bu dataları kullanıyor olacağız. Şimdi İlk örneğimiz şöyle bir şey olsun. X kategorisine ait tüm ürünleri listeletelim ve dönen ürün listesinden stok durumu 5 ten az olanları alalım. Ayrıca o ürünlere ait Kategori Adlarınıda Yazdırmayı ihmal etmeyelim. Biraz karışık gibi görünsede gayet kolay olacak emin olun :).

Proje Dosya Adı : ExtraObjects.aspx (Markup ve Code Behind ayrı ayrı verilmiştir.)

[Markup]

<asp:GridView ID="GridView1" runat="server" CellPadding="4" ForeColor="#333333"

    GridLines="None" Width="100%">

    <RowStyle BackColor="#E3EAEB" />

    <FooterStyle BackColor="#1C5E55" Font-Bold="True" ForeColor="White" />

    <PagerStyle BackColor="#666666" ForeColor="White" HorizontalAlign="Center" />

    <SelectedRowStyle BackColor="#C5BBAF" Font-Bold="True" ForeColor="#333333" />

    <HeaderStyle BackColor="#1C5E55" Font-Bold="True" ForeColor="White" />

    <EditRowStyle BackColor="#7C6F57" />

    <AlternatingRowStyle BackColor="White" />

</asp:GridView>

[Code Behind]

protected void Page_Load(object sender, EventArgs e)

        {

            BindProducts();

        }

 

        protected void BindProducts()

        {

            Category[] categories = SampleData.GetCategoryData();

            Product[] products = SampleData.GetProductData();

 

            var product = from p in products

                          join c in categories on p.CategoryID equals c.ID

                          where p.CategoryID == 1 && p.Quantity < 5

                          select new { CategoryName = c.Name,

                                       p.Name,

                                       p.Price,

                                       p.Quantity

                                      };

 

            //Ürünleri GridView vasıtası ile kullanıcıya gösteriyoruz.

            GridView1.DataSource = product.ToList();

            GridView1.DataBind();

        }

Yukarıdaki kısım biraz karışık görünsede ilk başta kodları dikkatlice süzerek neyin ne olduğu hemen anlaşılıyor. Burada yaptığımız işlemleri hemen açıklayalım. BindProducts() adındaki void'ımız içerisinde ilk başta 2 adet dizi değişken tanımlıyoruz. Bunlardan ilk Kategorileri ikincisi ise ürünleri tutuyor. SampleData dan ilgili metodları çağırarak içerilerine verileri dolduruyoruz. Sonraki satırda Linq kodlarımızı yazmaya başlıyoruz. Bu kısımda daha önce hiç görmediğimiz join ve on reserve sözcükleri dikkatimizi çekebilir. equals sözcüğünü zaten bildiğinizi varsaydığım için ona değişmedim. Ama bilmeyen arkadaşlar için equals eşitlik anlamına gelir diyelim. Sonrasında iki nesneyi birbirine bağlamak için join sözcüğünü kullandık. on ile hangi tablo arasında bağlantı sağlanacağı ve hangi alanı dikkate alacağı belirtildi. p yani Products ı temsil eden nesnenin CategoryID si ile c nin yani kategoriyi temsil edeh nesnenin ID si birbirine eşit olanları bağla dedik. Sonraki satır where sözcüğü ile Ürünün categoryID si 1 olan ve Yine Ürünün stok durumu 5 ten küçük olanları süzdürdük. En son satırda yine daha önce görmediğimiz bir takım yenilikler geldi. new sözcüğü ile istediğimiz alanları işaretleyip sadece onların görünmesini sağlıyoruz. Ayrıca String birleştirme ve hesaplama işlemlerinide bu alanda rahatlıkla yapabiliyoruz. Fakat hesaplama işlemlerine daha sonra bakacağız. Dikkat edilmesi gereken ilk konu aşağıdaki iki satır. Neden birisi farklı birisi farklı ?

CategoryName = c.Name,

p.Name,

 

Bir nesnede aynı isime sahip bir özelik ve/veya kolon var ise derleyicimiz "An anonymous type cannot have multiple properties with the same name" hatası verecektir. Bunu önlemek için Geçici bir field(alan) yaratıp o şekilde kullanmamız gerekir. SQL tarafına çevirmek gerekirse bu alan oluşturma işini Select c.Name as [CategoryName] From tablo olacaktır. En son olarak GridViewimizi databind ettik. Şimdi aşağıda sonucu inceleyelim.

 

 

Linq ne kadar faydalı ve güzel bir şey değil mi ? Bu makalemizde bu kadarıyla yetinip diğer bir makalede görüşmek dileği ile diyoruz.

 

Diğer makalelerimizde neler olacak ?

 

  1. Linq ile string birleştirme
  2. Hesaplama işlemleri
  3. Linq To SQL Giriş
  4. İleri seviye Linq Sorguları
  5. Baştan sona Linq İle Web Projesi
  6. Baştan sona Linq İle Windows Projesi
  7. Baştan sona Linq İle Silverlight
Örnek Proje Dosyası