yazılım,c# ve domates kabuğu
« Invariant Case Türkçe İ ve I karakterleriProduct vs Platform şirketleri »

beklenen linq tepkisi

  27/12/11 20:28, by ertan, Categories: Algoritma Soruları

beklenen linq tepkisi

İlk çıktığı zamandan beri mümkün olduğu kadar uzak durduğum linq ile ilgili beklentim boşa çıkmadı. Linq to sql'in geliştirilmesine son verildi. Okuduğum yorumlardan çoğu kişi bu konuya baya bir sinirlenmiş ve şaşırmış. Hatta open source yapın biz bakarız diyenleri bile var.

İşin aslı ben o kadar fazla şaşırdım diyemem, sebebi ise şimdiye kadar uzak durmam ile aynı sebep.

Henüz gün ışığı almamış yazılımcılarımız için biraz geçmişten bahsedeyim. Aşağıda Microsoft'un her biri için zamanında "bakın süper oldu! hadi kullanın" dediği data access teknolojilerinin listesi var.

Bu listenin içinde şimdi kullanayım dediğinizde şu anda sadece ADO.NET kullanılabilir durumda, bunun dışında yeni gelmiş Linq2SQL ve Entity Framework var. Üzerinde geliştirme yapılabilen diğer platformlar (Java gibi) ile karşılaştırdığınızda Microsoft'un bu Data Access konusunda bir türlü karar veremediğini görürsünüz.

Şimdi bu yazıyı okuyupda beni Microsoft düşmanı filan sanmayın, Microsoft sayesinde para kazanan biriyim, hatta mecbur kalmadığım sürece Java yada benzeri bir şey ile ilgim olmaz.

Geçen o kadar yıldan sonra emin olduğum tek şey var. Data Access konusunda Microsoft'a güvenme.

Neden ?

Microsoft eşlenik olduğu rakipleri içerisinde geliştiricilere en çok önemi veren şirket, ürettiği herşeyde "platform" tadı vardır ama belli konularda her zaman "kaygı ayrılığı" durumu yaşanır. MS'inde güçlü ve zayıf olduğu yerler var, örneğin yaptığınız projenin Oracle veritabanı ile çalışıyor olmasını (gayet doğal olarak) tercih etmez.

Eğer tek atımlık bir projeden bahsediyorsak bu veritabanı taşınabilirliği o kadar önemli olmayabilir ama eğer mermi adedi belirsiz bir üründen bahsediyorsanız ortaya çıkacak ürünün tüm sinir, sindirim ve dolaşım sisteminde Sql Server, Active Directory gibi MS ürünlerinin bulunmasını ister.

Bu yüzden MS belli konularda (data access gibi, IIS gibi) geliştiriciler ile bağlılık arasında kendi kendine sürekli bir savaş yaşar. Eğer mobility'ye çok açık bir durum var ise bir süre sonra Entity Framework benzeri yeni bir versiyon çıkar ortaya. Yukarda listesini gördüğünüz data access componentlerinin sayısının çok olmasının nedeni budur.

Linq ile derdim

Bilmeyenler için önce ufak detay vereyim. Linq, IQueryable ve Expression denilen bir yapı üzerine kurulu ve siz bu IQueryable ve Expression'lar ile bir sorgu hazırlayarak, herhangi bir sisteme execute edilmesi için gönderiyorsunuz. Bu sistem bir c# array'i olur veya db olur çok fark etmiyor, hatta birden fazla sistemi birbirine join bile edebilirsiniz.

Linq2SQL ise database'de duran tablolara göre üretilmiş/generate edilmiş classlar'a göre bu Expression'ları SQL komutlarına çevirerek çalışan bir mantıkta zaten.

Öncelikle lambda konusu benim gözümde anonymous delegate'lerin biraz daha şekillisi, kolay kullanılanı. Eğer dümdüz, 1 kez yazdığınız zaman işiniz bitecek ise kullanmamak için hiç problem görmüyorum.

Eğer reuse ihtimali olacak bir kod yazıyorsanız, sorunlar o zaman başlıyor.

Serialization

Linq'in açılımı "Language Integrated Query" demek. Eğer bir query dilinden bahsediyorsak benim ilk baktığım, sorgunun nasıl serialize edildiğidir. Eğer serialize edemiyorsam disk'e kaydedemem, networkden geçiremem, viewstate'e yazamam.

Örneğin serialization var ise örneğin müşterileri listeyecek bir servis yapıyorsam;

Code

Customers[] GetCustomers( Expression query );

gibi bir metodla dışardan gelcek sorguyu dinamik olarak çalıştırabilirim. Eğer yapamıyorsam aşağıdaki gibi her case için ayrı düşünmem gerekli.

Code

Customers[] GetCustomers( int? id, string name, ... );

Linq için baktığımız zaman, Expression class'ı "by design" olarak query'ler serialize edilemiyor. Bu konuda WCF içerisinde geçen buradaki bilgi var. Okuduğum kadarıyla pek tatmin edici değil, ciddi işler için kullanılabilecek bir boyutta değil.

Type-Safety

Sorgu dili direk c# içerisine gömüldüğü için hazırlanan sorgu ilgili Type'a göre değişiyor. Yani genel bir sorgu yazayım istediğim yere göndereyim gibi bir mantık olamıyor, mutlaka bir class tanımı istiyor.

Örneğin bir Xml dosyasındaki entity tanımlarına göre çalıştıramıyorsunuz. Bu yüzden dinamik bir yapı kurmanız çok zor. ( Eğer arka tarafda xml'e bakarak otomatik class generate edecek bir yapınız yok ise, bu da yapanı var gördüm.)

Bazıları ne yaptın, o kadarda değil diyebilir, en fazla ne yapabileceğinize örnek vereyim.

Code

var xml = XElement.Load("nurettin.xml");
 
 
 
  string t = "Belluci";
 
  var v = from page in xml.Elements("SitePage")
 
    where t == page.Element("Title").Value
 
    select page;

Bu xml içerisinden linq ile sorgulamanın bir örneği. Aynı şeyi birde xpath (evet w3c standardı) ile deneyelim.

Code

var xml = new XmlDocument().LoadXml("nurettin.xml");
 
  
 
  var page = xml.SelectNodes("//SitePage[Title ='Belluci']");

Hmm..

Yazım şekli (syntax)

Kolay anlaşılması için standart c# ile yazılmış bir kod parçası üzerinden gidelim. Aşağıda 2 array içinde eşleşen kayıtları bulan bir kod parçası var.

Code

foreach (string g1 in sourceGroups)
 
{
 
   foreach (string g2 in targetGroups)
 
   {
 
       if (g1 == g2)
 
       {
 
           matches.Add(g1);
 
       }
 
   }
 
}

Aynı kodun birde linq ile yazalım;

Code

maches.AddRange(
 
  from g1 in sourceGroups
 
    from g2 in targetGroups
 
      where g1 == g2
 
        select g1);

Bunlardan hangisine baktığınızda 5sn içerisinde ne olduğunu anlıyorsunuz ? Anlaşılır, temiz syntax'ın cevabı ile aynıdır bu. Sizi bilmem sql-vari dil bana pek anlaşılır gelmiyor.

Özet

Eğer tek atımlık bir iş yapıyorsanız, yazdığınız koda geri dönüşünüz az olacak ise Linq gayet kullanılabilir, c# içerisindeki Query sorunlarını halledebilecek bir yapı. Buna uzun süredir de ihtiyaç vardı.

Eğer API gibi, extend-reusability falan istiyorsanız c# sınırları dışına çıkmayan bir API içerisinde yine kullanılabilir ama dış dünyaya açtığınız kapılardan Linq geçirmemeniz sizin için faydalı olacaktır.

Linq2SQL'in ise geleceğine zaten Microsoft karar vermiş gözüküyor.

1 comment

Comment from: Bebe [Visitor]
Bebe

from g1 in sourceGroups
join g2 in targetGroups on g1 equals g2
select g1;

28/12/11 @ 22:01

Leave a comment


Your email address will not be revealed on this site.
  
(For my next comment on this site)
(Allow users to contact me through a message form -- Your email will not be revealed!)
Text Renderers: