Herkese merhabalar
Bu yazımda sizlere ADO.NET Entity Data Model aracıyla oluşturduğumuz bir veri modeli üzerinden örnek linq sorguları yazmaya çalışacağız ve bu sayede sorgumuzda bulunan diğer kavramlarada değinmeye çalışacağım.
Örnek sorgularımızı Visual Studio 2010 IDE si üzerinden bir console uygulaması oluşturarak yapıyor olacağız.İnternette kolaylıkla bulabileceğiniz kobay veritabanı olan Nortwind ın Entity Modelini oluşturacağız.
Linq hakkında bilgi sahibi değilseniz ilk önce daha önce yazmış olduğum bu yazıyı okumanızı öneririm bu sayede linq teknolojisinin geneli hakkında bilgi sahibi olacaksınız.Linq ; daha önceleri “” içerisine yazdığımız t-sql sorgularını dilin içerisinde entegre şekilde yazabilmemizi sağlayan bir alt yapıya sahip ve bunun için t-sql de kullandığımız anahtar kelimeleri (select,where..) dilin içerisine taşımış olması önemli bir gelişmedir.Linq dosya işlemelerinde ,bağlantısız katmanda kullanımının yanısıra o kadar farklı bir hale geldi ki 3party bileşenler üretilerek Twitter, Facebook gibi çeşitli kaynakları kullanan LinqToTwitter ,LinqToFacebook gibi farklı amaçla kullanımlarıda mevcuttur.Temelde sorgulama işlemlerinde kullandığımız yapılar,keywords değişmiyor sadece veri kaynağı değişiyor.
Fazla uzatmadan örneğimize geçelim.Örneğimizde Nortwind veritabanından Products ve Categories isimli tabloları,Products_by_Category adındaki view ve Ten_Most_Expensive_Products isimli stored procedure kullanacağız.
Modelde gördüğünüz gibi tablolar ve view ler görünüyor.Daha sonra Stored procedure ü kullanmak için model üzerinde yapacağımız ayarlara değineceğim.Sabırsızlanmayın
SORGU-1
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
using (NorthwindEntities context = new NorthwindEntities()) { var result = from c in context.Categories from p in context.Products where c.CategoryID == p.CategoryID select new { CategoryName = c.CategoryName, ProductName = p.ProductName }; foreach (var item in result) { Console.WriteLine( "{0}......{1}" , item.ProductName, item.CategoryName); } } |
Yukarıdaki sorguda anladığınız üzere iç içe select sorgusu çalıştırılmakta.Categories tablosundaki her satır için başka bir select işlemi yapılıyor ve bu işlemde categoryId leri eşit olan satırlar sıralanıyor.Arka planda bu linq sorgu için çok fazla t-sql sorgu ifadesi çalışıyor. Performans açısından düşündüğünüzde bu linq sorgusu iyi değildir.
New ile bir isimsiz tip (Anonymous types) oluşturularak bir sonuç elde edilmeye çalışılmış.İsimsiz tipleri daha çok sorgu sonucunda kendi belirlediğimiz bir veri setini geri döndürmek için kullanırız ve İsimsiz tipler arka planda StringBuilder nesnesi ile oluşturulur.
NorthwindEntites context nesnemiz using blogu içerisinde kullanılmıştır.Bunun sebebi dispose işlemini otomatik olarak yapmasıdır.using blogunda IDisposable arayüzünü implemente etmiş nesneleri kullanabiliriz ve bellekte konuşlanan nesnelerimizi işlem sonunda bellekten silinmesini using blogu sağlar ve içerisinde yazılan işlemler biter bitmez context nesnesinin dipose işlemini gerçekleştirir.
SORGU-2
1
2
3
4
5
6
7
8
9
10
11
12
13
|
//View kullanarak using (NorthwindEntities context = new NorthwindEntities()) { var result = from d in context.Products_by_Categories where d.UnitsInStock > 100 && d.ProductName.Contains( "a" ) orderby d.ProductName ascending select d; foreach (var item in result) { Console.WriteLine( "{0}...{1}...{2}" , item.CategoryName, item.ProductName, item.UnitsInStock); } } |
Aynı şekilde garantili dispose işlemi için context nesnemiz using blogu ile üretilmiş.Veritabanı tarafında da oluşturulan View leri tablo olarak kullanabiliyorduk burada da modelimize eklediğimiz view i sorgumuzun veriseti olarak kullanıyoruz.Bu view her ürün ve bu ürünün bağlı olduğu kategoriyi tek bir yapıda toplamış.Bu sorguda ürünlerin stokdaki adedi 100 den büyük ve ürün isminde a harfini içeren ürünleri sıralıyor.Order by ile ürün adına göre a..z ye bir sıralama söz konusu. Oluşan sonuç kümesi içinde foreach ile dolaşarak istenilen alanları yazıyoruz.Oluşan ekran görüntüsüne bir bakalım.
SORGU-3
1
2
3
4
5
6
7
8
9
|
using (NorthwindEntities context = new NorthwindEntities()) { var result = context.Products.Where(d => d.Discontinued == true ).ToList(); foreach (Product item in result) { Console.WriteLine( "{0}...{1}" , item.ProductName, item.Discontinued); } } |
Sorgumuzda Products tablosunun where genişleme methodu ( extention method) kullanılarak bir seçim işlemi yapılmaya çalışıyoruz fakat bu methodun içerine kriterimizi Lamda operatörü kullanarak yapıyoruz.Lamda operatörü => dür.Aslında fonksiyon olarak düşünebiliriz.Products tablosu içerisinden bana öyle bir satır seç ki Discontinued alanı true olsun. Dikkat ettiyseniz foreach içerisinde her bir satırı Product Entity olarak tanımladım.Sorgu sonucunda oluşan veri seti zaten product tablosundan bir liste döndürüyor.
SORGU-4
1
2
3
4
5
6
7
8
9
|
using (northwindentities context = new northwindentities()) { var result = context.products.tolist().skip(3).take(5); foreach (var item in result) { console.writeline( "{0}...{1}" , item.productname, item.unitsınstock); } } |
Sorgu ifadesinde aslında linq sorgusu yok tamamiyle entityframework in bize sağladığı nimetlerden faydalandık.Context üzerinden Products tablosunu içerisindeki dönüştürme operatörü olan (partitioning operator) ToList methodu üzerinden Skip ve Take operatörleri kullanılmış.Bu sorguda amaç Products listenden 3.satırdan başlayarak 5 adet ürün bilgisi çekmemizi sağlıyor.Entityframewok ün bize sağladığı çok faydalı ve bazen hayat kurtaran fonksiyonellikleri kullanmak gerektiğini düşünüyorum.
SORGU-5
Şimdi Modele eklediğimiz Ten_Most_Expensive_Products adındaki Stored Procedure ü nasıl kullanacağımıza bir bakalım.Model görünümüne geldiğinizde yan kısımda Model browser ın çıktığını görüceksiniz bu kısımdan gerekli tanımlamaları yapmamız gerek.Stored Procedure ü complex type olarak modelimize ekliyor olacağız.
Daha sonra modele eklemek için farklı bir ekran gelecek bu ekranda yeni bir complex type oluşturalım ve yeniden isimlendirelim.
Eğer gerekli ayarları yaptıysanız model browser üzerinden modelinize baktığınızda complex type inizin oluştuğunu görüceksiniz şimdi bu stored procedure ümüzü kullanalım.
1
2
3
4
5
6
7
8
9
|
using (NorthwindEntities context = new NorthwindEntities()) { ObjectResult<MostExpensiveProducts> result = context.MostExpensiveProducts(); foreach (var item in result) { Console.WriteLine( "{0}...{1}" , item.TenMostExpensiveProducts, item.UnitPrice); } } |
Gelen result seti ObjectResult olarak alıyoruz.Bu nesneyi kullanmak için kod sayfanıza System.Data.Objects isim alanını eklememiz gerekiyor.Kısaca entityframework üzerinde stored procedure kullanımına da değinmiş olduk.Sonucu görmek ister misiniz ?
SORGU-6
Master-detail ilişkisine sahip tabloları eklemiştik şimdi de join sorgusu yazalım ve inceleyelim.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
|
using (NorthwindEntities context = new NorthwindEntities()) { var result = from p in context.Products join c in context.Categories on p.CategoryID equals c.CategoryID select new { CategoryName = c.CategoryName, ProductName = p.ProductName }; foreach (var item in result) { Console.WriteLine( "{0}...{1}" , item.CategoryName, item.ProductName); } } |
Bu sorguda ; Categories tablosu ve Products tabloları arasında CategoryID alanına bağlı olarak category adları ve ürün adlarını çekiyoruz.Normal olarak ürün ve kategorilere ait bir çok alana ulaşabiliyoruz fakat result set için bir isimsiz tip oluşturduk ve sadece kategori adı ve ürün adını aldık.
SORGU-7
1
2
3
4
5
6
7
8
9
10
|
using (NorthwindEntities context = new NorthwindEntities()) { var result = (from d in context.Products select d.Category.CategoryName).Distinct(); foreach (var item in result) { Console.WriteLine( "{0}" , item.ToString()); } } |
Bu sorguda temel konumuz Distinct operatörü nün işlevi üzerinedir.Distinct operatörü belirtilen alanın tekrarsız bir şekilde elde edilmesini sağlamak için kullanılıyor.Bu sorgumuz products tablosunda bulunan ürünlerin kategori alanlarını tekrarsız bir şekilde elde etmemizi sağlıyor ve dikkat ederseniz bunu products tablosu üzerinden yapıyoruz peki bu işlemi category tablosu üzerinden de yapabilir miyiz ? yapamayız çünkü aynı result seti vermez products tablosunda bulunan ürünler belirli bir kategoriye sahip ürünlerdir yani ürüne sahip kategorileri çekiyoruz.Eğer kategori tablosunda bu işlemi yapasaydık ürün eklenmemiş kategorileride elde etmiş olacaktık.
SONUÇ
Bu yazımızda 7 linq sorgusuyla ile linq dünyası içerisinde sıcak bir gezinti yaptık.C# 3.0 ile birlikte gelen isimsiz tiplere(anonymous types),Lamda operatörüne(=>) ,Entity Framewok ile stored procedure ü nasıl çalıştıracağımızı kısaca incelemiş olduk.Özellikle ADO.NET Entity Framework bize gerçekten çok yararlı fonksiyonellikler sunuyor bunları kullanmakta yarar var Bundan sonraki yazılarımda daha çok Entity Framework üzerine yazılar yazmayı düşünüyorum. Umarım anlatabilmişimdir
İyi çalışmalar
Comments 0