2 Eylül 2009
.Net Compact Framework 3.5 – System.IO.Compression
Bu makalemizde .Net Compact Framework 3.5 ile mobil cihaz uygulama geliştiricilerin kullanımına sunulan ve mobil cihaz uygulamalarında sıkıştırma işlemlerine olanak sağlayan System.IO.Compression namespace’ i içerisindeki sınıfları inceleyecek, örnek bir uygulama geliştiriceğiz.
Bilgisayarların tüm gelişim tarihi boyunca farklı ihtiyaçlar üzerinde birçok metodoloji geliştirilmiş ve tüm bu metodolojiler zamanla standart bilgisayar hayatımıza girmiş bulunmaktadır. İnsanoğlunun bu gelişim sürecinde üzerinde çalıştığı en önemli nokta ise temel olarak byte dizileri olarak adlandırılan veri kümelerini bilgisayar ortamında daha efektif ve daha iyi nasıl depolanacağıdır. Bu noktada araştırıldığında ise zaman içerisinde bu veri kümelerinin taşınılabilirlilik ve depolama noktasında hayatımızı kolaylaştırabilmesi açısından birçok çalışma gerçekleştirilmiş ve bugün birçoğumuzun günlük hayatında farkında olmadan yüzlerce kez kullandığımız yöntemlere dönüşmüştür.
Bu metodolojilerin en başında hepinizin tahmin edebileceği üzere sıkıştırma (zip / unzip) işlemleri gelmektedir. Sıkıştırma mantığına temel olarak bakıldığında böyle bir işlemin gerçekleştirilebilmesi için gereken yazılım kodlanabilmesi için çok yüksek bir matematik bilgisine ve bu matematik bilgisini yazılımsal olarak destekleyebilecek programlama bilgisine sahip olunması gerektiği kolay bir şekilde anlaşılabilmektedir. Sıkıştırma işlemleri tüm gelişim tarihi boyunca çok önemli bir yer kaplamış, farklı algoritmalar üzerinden bugünkü standart olarak kabul edilebilecek ve günlük hayatta yüzlerce kez kullandığımız / kullanıyor olduğumuz halini almıştır. Bugün araştırıldığında en meşhur ve en çok kullanılan sıkıştırma uygulamalarının arka tarafında tarihteki en meşhur sıkıştırma algoritmalarından Deflate Algoritması kullanılmaktadır. Deflate algoritması ile ilgili ayrıntılı bilgiye http://en.wikipedia.org/wiki/DEFLATE_(algorithm) adresinden ulaşabilir, bu algoritmanın arka tarafındaki matematiksel altyapıyı öğrenebilirsiniz.
Bu makalemizde ise bu algoritmaları kullanan sınıfların hazır olarak tanımlandığı System.IO.Compression namespace’ i içerisindeki sınıfları kullanarak mobil cihaz uygulamalarında sıkıştırma işlemlerinin nasıl gerçekleştirilebileceği ile ilgili konuyu ifade edecek ve örnek bir uygulama geliştirilecektir.
Hızlı bir şekilde .Net Compact Framework 3.5 ile mobil cihaz uygulamalarında hayatımıza giren sınıfları tanımaya geçelim.
Öncelikle belirtmemiz gerekirki bu sınıfları masaüstü .net Framework uygulama geliştiricileri .net Framework 2.0 sürümünden beri kullanmakta, kendi uygulamalarında Deflate algoritması üzerinden sıkıştırma işlemleri gerçekleştirebilmektedirler. Biz ise bugün .net Compact Framework 3.5 ile mobil cihaz uygulama geliştiricilerinde hayatına giren bu sınıflarla mobil cihaz üzerinde çalışan ve zip / unzip işlemleri gerçekleştirebileceğimiz bir uygulama geliştireceğiz.
Üstteki resimden de anlaşılabileceği üzere System.IO.Compression içerisinde aslında birbiriyle küçük bir fark dışında tamamen aynı iki adet sınıf bulunmaktadır.
DeflateStream adından da anlaşılabileceği üzere Deflate algoritmasını kullanarak sıkıştırma ve açma işlemi gerçekleştirmeye yarayan altyapıyı içerisinde barındırmaktadır. GzipStream ise yine Deflate algoritmasını kullanmaktadır, fakat içerisine Gzip dosya formatına uygun bazı başlık bilgileri eklemekte, dolayısıyla gzip uzantısına sahip dosyaları açabilecek tüm uygulamalarda açabilecek hale getirmektedir.
Hiç vakit kaybetmeden Visual Studio 2008 üzerinde bir mobil cihaz uygulaması açarak işe başlayalım. Bu noktada belirtmemiz gerekise geliştirilecek olan uygulamanın hedef platformu Windows Mobile 6.0 yüklü dokunmatik özelliğe sahip (Windows Mobile 6.0 Professional) cihazlar olduğundan dolayı ilgili SDK’ yı sisteminize kurmanız gerekmektedir. İlgili SDK ‘ yı http://www.microsoft.com/downloads/details.aspx?familyid=06111A3A-A651-4745-88EF-3D48091A390B&displaylang=en adresinden indirebilirsiniz. Visual Studio üzerinde bir mobil cihaz uygulaması oluşturarak hızlı bir şekilde örnek projemizi geliştirmeye başlayalım.
Projemizin adı MobiZip.
Hedef platformumuz ise Windows Mobile Professional 6 SDK üzerinde .Net Compact Framework 3.5 sürümü olacaktır.
Uygulama ekranını tasarlamaya geçmeden önce hızlı bir şekilde uygulamamızın senaryosunu ifade edelim.
Uygulamanın temel amacı mobil cihaz üzerinde konumlandırılmış bir dosyayı sıkıştırmak ya da belirli koşullar sağlandığı taktirde bu sıkıştırılan dosyayı açıp tekrardan eski haline getirmektir. Bu noktada bu koşulları ifade etmemiz gerekirse ;
Uygulamamızın kullanacak olduğu dosya uzantısı DosyaAdi.mobizip olacaktır. DeflateStream yapısı gereği dosyanın sıkıştırılmadan önceki adı ve boyut bilgisini tutmadığından ve dosyanın eski haline getirilmesi noktasında bu bilgilere ihtiyaç duyulacağından sıkıştırılmış dosyanın yanına uzantısı DosyaAdi.mobizip.info olan bir bilgi dosyası daha oluşturulacaktır. Bu dosya içerisinde arasında | işareti koyularak dosyanın orjinal adı ve sıkıştırılmadan önceki boyutu kaydedilecektir.
Hızlı bir şekilde uygulama ekranını tasarlayalım.
Uygulama ekranına baktığımızda çokta karmaşık bir arayüz olmadığını, ihtiyaçlar noktasında sıkıştırma yada açma işlemi gerçekleştirilecek olan dosyanın seçilebilmesi için gereken 3-4 adet kontrol yerleştirilmiştir. Ayrıca ekran üzerinde görünmeyen ve dosya seçme diyaloğunu temsil eden OpenFileDialog kontrolüde arayüz üzerine yerleştirilmitir. (OfdSelectFile)
Hızlı bir şekilde kod altyapısını oluşturmamız gerekirse ;
Senaryo gereği kullanıcı OpenFileDialog vasıtasıyla sıkıştırılacak yada açma işlemi gerçekleştirilecek dosyayı seçecektir.
... yazan button’ a tıkladığımızda aşağıdaki kod bloğu çalıştırılacaktır.
Yukarıdaki kod bloğundan anlaşılabileceği üzer dosya seçme ekranı üzerinden herhangi bir dosya seçildiğinde bu dosya bilgisi metin kutusu içerisine yazdırılmaktadır.
Bir sonraki aşamada sıkıştırma işlemlerinde kullanacak olduğumuz 3 adet stream obje referansını global’ e yerleştiriyoruz.
Bu noktada açıklamamız gerekirse ; DeflateStream adından da anlaşılabileceği üzere sıkıştırma ya da açma işlemlerini gerçekleştirecek olan Stream objesini temsil etmektedir. FsSource senaryoya göre o an işleme sokulan dosyanın stream’ i FsTarget ise o an senaryoya göre işlem görecek olan dosyanın stream’ ini temsil etmektedir.
Sıra geldi sıkıştırma / açma işlemlerini gerçekleştirecek olan Operate button’ una tıklandığında çalıştırılacak olan kod bloğunu hazırlamaya geldi.
Uygulamamız hangi işlemin yapılacağına (sıkıştırma / açma) seçilen dosyanın türüne bakarak karar verecektir. Eğer seçilen dosyanın uzantısı *.mobizip ise açma, değilse sıkıştırma işlemi gerçekleştirecektir. Aynı zamanda *.mobizip uzantısına sahip olsa bile dosyanın eski haline getirilebilmesi için gereken *.mobizip.info dosyasınıda sıkıştırılmış dosyanın yanında arayacak şayet bulabilirse hata vermeden işlemi tamamlayacaktır.
Operate tuşuna basıldığında ilk olarak dosyanın türünü inceliyoruz ;
Bu if koşulunun else ayağında ise sıkıştırma işlemi gerçekleştirilmektedir.
Hızlı bir şekilde uygulamamıza devam edelim. Eğer seçilen dosya mobizip uzantısına sahip ise açma işleminin yapılacağı ile ilgili kod bloğu çalıştırılmaktadır. Bu kod bloğunda ise ilk olarak ilgili dosyanın bilgilerinin bulunduğu info dosyası aranmaktadır.
Dosya eğer başarılı bir şekilde bulunabilmiş ise dosya içeriği | işaretine göre split edilmekte ve bir diziye aktarılmaktadır.
Bir sonraki aşamada açma işlemi için gereken kodlar yazılmaktadır.
Yazılan kodları sırasıyla incelediğimizde ilk olarak global’ de tanımlanan Stream objelerinin instance’ ları oluşturulmakta ; FsSource açılacak olan dosyayı temsil etmekte, FsTarget ise açıldıktan sonra oluşturulacak olan eski dosyayı temsil etmektedir.
DeflateStream objesinin instance’ ının oluşturulduğu satırda ise ilk parametresinde açılacak olan stream’ a referans, ikinci parametresinde ise gerçekleştirilecek olan işlem seçilmiştir.
Bir sonraki satırda info dosyasının yardımıyla dosyanın açıldıktan sonraki halinin byte dizisini depolayabilecek bir buffer oluşturulmuş, boyut olarakta yine info dosyasının yardımıyla eski dosyanın (sıkıştırılmadan önceki) boyutu atanmıştır.
ds.Read ile başlayan satırda sıkıştırılmış dosyanın tekrardan açılmış hali buffer ‘ a kopyalanmakta,bir sonraki satırda ise buffer içerisindeki açılmış hali FsTarget stream’ i üzerinden yeni oluşturulmuş ve açılmış olan dosyaya yazılmaktadır. İşte bu kadar ! Bu noktadaki en önemli uyarı ise stream’ leri kullandıktan sonra kesin olarak kapatmanızdır. Aksi taktirde dosyalara erişim kısıtlanacak ve hata alınacaktır.
Bir diğer çalıştırılacak olan kod bloğu ise sıkıştırma işlemi için gereken kod bloğudur. Uygulama uzantının *.mobizip olmadığı durumlarda sıkıştırma işlemi gerçekleştirmekte ; bununla birlikte bir info dosyası oluşturmaktadır.
Yukarıdaki kod bloğu incelendiğinde ise aslında bir önceki işlemle karşılaştırıldığında tam ters hareket uygulanmaktadır.
İlk iki satırda sıkıştırılmış ve sıkıştırılacak olan dosyalar ilgili stream’ lere yüklenmekte, bir sonraki aşamada ise dosya bilgilerinin tutulduğu FileInfo değişkeni oluşturulmaktadır.
Daha sonra sıkıştırılacak olan dosyanın verileri Buffer’ a yüklenmekte, ve DeflateStream üzerinden FsTarget isimli stream’ e bu veriler sıkıştırılarak gönderilmektedir.
Bu işlemden sonra *.mobizip.info uzantılı dosya da kaydedilmekte ve işlem tamamlanmaktadır. İsterseniz hiç vakit kaybetmeden uygulamamızı Emulator üzerinde deneyelim.
Uygulamamızı çalıştırdığımızda aşağıdaki görüntüyü elde etmemiz gerekmektedir.
Dosya seçme ekranını açarak daha önceden cihaza kopyaladığımız ve sıkıştırılmaya çok müsait olan bir BMP dosyasını seçiyoruz.
Ve son görünüm,
Operate tuşuna tıkladığımızda uygulama dosyanın uzantısına bakacak ve sıkıştırma işlemi gerçekleştirecektir.
Dosyanın bulunduğu yere gidip baktığımızda dosyanın yanında 2 adet daha dosya görmekteyiz. Bunlardan biri sıkıştırılmış olan dosya (*.mobizip) ve sıkıştırılan dosyanın eski boyut bilgisi ve isim bilgisini tutan *.mobizip.info dosyası.
Dikkat edilecek olursa dosya boyutu neredeyse 20 kat küçülmüştür.
Bir sonraki aşamada OrnekBMP isimli bmp dosyasını siliyoruz.
Ve bu dosyayı sıkıştırıldığı halinden tekrar oluşturuyoruz.
Öncelikle uygulamamızdan mobizip uzantılı sıkıştırılmış dosyayı seçiyoruz.
Operate tuşuna bastığımda ise açma işlemi başarıyla gerçekleştirilmektedir ;
Dosyanın bulunduğu yere tekrar gidip baktığımızda ;
Dosyanın tekrar oluşturulmuş olduğunu görmekteyiz.
İşte bu kadar !
Bu makalede .net Compact Framework 3.5 ile birlikte gelen System.IO.Compression sınıflarını kullanarak bir sıkıştırma / açma işleminin nasıl gerçekleştirilebileceği ile ilgili örnek bir uygulama geliştirdik.
Başka bir makalede daha görüşmek dileğiyle.
1 Eylül 2009
.Net Compact Framework 3.5 – WCF Servislerinin Kullanımı
Bilindiği üzere .net Compact Framework 3.5 sürümünün en heyecan verici yeniliklerinden birtanesi halihazırda kullanılıyor olan WCF servislerine “belirli kısıtlamalarla” erişilmesine verdiği destektir. Windows Communication Foundation, kısa adıyla WCF, .Net Framework 3.0 ile birlikte hayatımıza giren yeni nesil dağıtık uygulama geliştirme iletişim arabirimidir. Birçok dağıtık uygulama geliştirme teknolojisini bünyesinde barındıran WCF, dekleratif konfigürasyon özelliğiyle servis geliştiricilerin hayatını ciddi anlamda kolaylaştırmaktadır. Bu yazımızda hali hazırda kullanıyor olduğumuz basit bir WCF servisine .Net Compact Framework 3.5 kullanılarak geliştirilmiş bir mobil cihaz uygulamasında nasıl ulaşabileceğimizi ve servis çağrılarının nasıl gerçekleştirilebileceğini örneklendireceğiz.
Örneğimize başlamadan önce .Net Compact Framework 3.5 üzerinde desteklenen WCF içeriği hakkında kısaca bilgilenelim. Bilindiği üzere .Net Compact Framework 3.5 üzerinde sınırlı bir WCF desteği verilmektedir. Bu noktada belkide hissedebileceğimiz en büyük eksiklik hali hazırda kullanabiliyor olduğumuz Binding’ lerden sadece basicHttpBinding’ in destekleniyor olmasıdır. Bunun dışında Custom Binding, WindowsMobileMailBinding ve ExchangeWebServiceMailBinding desteklenmektedir. .Net Compact Framework 3.5 üzerinde desteklenen WCF’ in tüm özelliklerine http://blogs.msdn.com/andrewarnottms/archive/2007/08/21/the-wcf-subset-supported-by-netcf.aspx adresinden erişebilirsiniz. Bunun dışında masaüstü uygulamalardan WCF servislerine bağlanmak istediğimizde Visual Studio 2008 üzerinde görsel olarak kullanabildiğimiz NetSvcUtil.exe aracı .Net Compact Framework 3.5’ ta direk desteklenmemekte, http://download.microsoft.com/download/6/2/0/6205ED05-E435-44FC-AA82-B763CA5F8B1A/NetCFSvcUtil.exe adresinden indirebileceğiniz NetCFSvcUtil.exe vasıtasıyla Proxy sınıfları oluşturulabilmektedir.
Hiç vakit kaybetmeden örneğimize geçelim. Örneğimiz 2 projeden oluşmaktadır ; mobil cihaz üzerinden çağrıda bulunacak olduğumuz WCF servisi ve çağrıda bulunacak olan mobil cihaz uygulamamız. İlk olarak WCF servisimizi geliştirelim.
WCF servisimiz için bir Console Application projesi açıyoruz ve System.ServiceModel referansını ekliyoruz.
Projemize ServiceLibrary adında bir klasör ekliyoruz ve klasör içerisine Service Contract’ ımızı tanımlayabilmemiz için bir Interface (Arayüz) ekliyoruz. IMobileService ismini verdiğimiz arayüzümüz içerisine aşağıdaki tanımlamaları yapıyoruz.
Bir sonraki aşamada Service Contract arayüzümüzü implemente ettiğimiz Service sınıfımızı oluşturuyoruz.
Ve sıra geldi konfigürasyona. Projemize App.config dosyasını ekliyoruz ve aşağıdaki servis konfigurasyonunu tanımlıyoruz.
Servis tanımlamasını yaptıktan sonra mobil cihaz uygulamamız üzerinden erişebileceğimiz bir Endpoint tanımlıyoruz. Endpoint’ in Binding parametresi basicHttpBinding değerine sahiptir. Ve son olarak Servis’ i Console uygulamamız üzerinden aşağıda kod bloğu vasıtasıyla başlatıyoruz.
Uygulamamızı başlattığımızda aşağıdaki görünümü elde etmiş olmak durumundayız.
Servis adresini tarayıcımız üzerinden ziyaret ettiğimizde ise ;
Servis metadata erişim sayfasına ulaşabilmekteyiz. Sıra geldi bu servise ulaşacak mobil cihaz uygulamasını geliştirmeye. Hızlı bir şekilde vakit kaybetmeden bir Mobil Cihaz projesi açıyoruz ve ekran üzerine bir metin kutusu ve bir button kontrolü yerleştiriyoruz.
Bilindiği üzere masaüstü uygulamalarından WCF servislerine erişebilmek adına ilgili Visual Studio üzerinde Proxy sınıflarını üreten görsel bir araç bulunmaktadır. Bu araca “Add Service Reference” menü elemanı üzerinden erişebilmektedir. Araç arka tarafta NetSvcUtil.exe aracını çalıştırmakta ve proxy sınıflarını barındıran ilgili çıktıları aracın çalıştırıldığı projeye eklenmektedir.
Araca tıkladığımızda uzaktaki WCF servisine erişecek Proxy sınıflarını oluşturacak aşağıdaki araç açılmaktadır.
Gelelim işin detayına. Böyle bir görsel araç mobil cihaz uygulama projeleri için maalesef bulunmamaktadır. İşin enteresanı standart Visual Studio ile Proxy sınıfını oluşturabileceğimiz NetCFSvcUtil.exe aracıda birlikte gelmemekte, yazının başında belirtilen adresten ayrıca indirilmesi gerekmektedir. Aracın indirilmesinden sonra servisimizi çalıştırıyoruz ve araca aşağıdaki komut değerlerini göndererek konsol üzerinden çalıştırıyoruz.
Ekran görüntüsünden de anlaşılabileceği üzere çalışılan servise bağlanılmış ve iki adet çıktı üretilmiştir. Bu çıktılar varsayılan lokasyona oluşturulmuştur. Bir sonraki aşamada yapmamız gerekenler bu çıktıları kopyalayıp mobil cihaz projemize yapıştırmak ve proxy sınıfını örneklendirerek çalışan servise ulaşmak olacaktır. Dosyaların ikisinide projemize kopyalıyoruz.
Ve button’ a tıkladığımızda aşağıdaki kod bloğunu yazıyoruz.
İşte bu kadar ! Proxy sınıfının bir örneğini oluşturup fonksiyonumu çağırıyoruz. Gerekli koşulları sağlayıp uygulamamızı çalıştırdığımızda ise ;
Hepsi bu kadar ! Mobil cihaz uygulamamız WCF servisi üzerinde tanımlı fonksiyonumuz ile haberleşmekte ve değerler karşı tarafa taşınmaktadır.
Geliştirilen örnek uygulamayı buradan indirebilirsiniz. Bir başka yazıda daha görüşmek üzere.
28 Ağustos 2009
Windows Vista SP2 ve Windows 7 İçin Yeni NetCFSvcUtil !
Merhaba,
Deneyenler ya da ilgilenenler bilecektir, .Net Compact Framework üzerinde halihazırda kullanıyor olduğumuz WCF Service proxy' lerini oluşturmak için "command line" üzerinden çalıştırılan "çok önemli bir araç" bulunmaktadır. NetCFSvcUtil.exe.
Bu araç vasıtasıyla WCF Service proxy' lerini oluşturmakta ve akabinde WCF Service çağrılarını yapabilmektesiniz.
Her nedendir ki bu araç Windows Vista SP2 ve Windows 7 üzerinde çalışmamakta, Proxy generation sürecinde hata vermekte ve çıldırtmaktaydı. Neyseki "uzuun" zamandır güncellenmeyen .Net Compact Framework Team blog' u üzerine 10 ağustos' ta eklenen çok önemli bir blog girdisini paylaşmak istiyorum.
NETCFSvcUtil.exe fix :
"Check out Manish’s blog on NetcfSvcUtil.exe crashing on some operating systems and the uploaded fix for it here."
Evet ! , bu işi "en sonunda" düzeltmişler. 7 Ağustos itibariyle adresinden güncellenmiş NetCFSvcUtil' i indirebilirsiniz.Devamını Oku...
27 Ağustos 2009
Microsoft Yaz Okulu 2009 | İzmir
Merhaba,
26 Ağustos 2009 günü Microsoft Yaz Okulu 2009 serisinin son durağı olan İzmir - İzmir Yüksek Teknoloji Enstitütüsündeydim. Havalimanından itibaren aşağı yukarı 1 saatlik "çeşme istikametine" doğru bir yolculuktan sonra (Evet Çeşme :) ) üniversiteye vardım.
Çok kalabalık, çok keyifli bir gündü. Özellikle kampüsün konumu ve havasının serinliği günün yorgunluğunu aldı götürdü.
Mobil teknolojiler üzerine bolca sohbet ettik, örnek uygulamalar geliştirdik.
Kısacası, güzel ve kalabalık bir gündü. Geliştirilen örnek uygulamayı buradan indirebilirsiniz.
Microsoft Yaz Okulu 2009 | İstanbul
Merhaba,
Fotoğrafların biraz geç ulaşması :) ve iş yoğunluğu sebebiyle gerçekleşen fakat blog' a bir türrlü ekleyemediğim bir etkinlikten bahsetmek istiyorum. Microsoft Yaz Okulu 2009 | İstanbul. 18 Ağustos 2009 tarihinde Microsoft Türkiye İstanbul ofisinde keyifli bir gün geçirdik.
Mobil cihaz uygulamaları hakkında bol bol sohbet ettik, vaktiğimiz elverdiğince örnek uygulamalar geliştirdik.
Eğitim kadrosu ! :)
Arkadaşlar Microsoft Türkiye ofisin terasın keyfini bolca çıkarttılar :)
Kısacası keyifli bir gündü. Geliştirilen örnek uygulamayı buradan indirebilirsiniz.
23 Ağustos 2009
.Net Compact Framework 3.5 – LINQ Uygulamaları – Linq To Dataset
Konu ile ilgili bir önceki yazımızda ifade ettiğimiz üzere .Net Compact Framework 3.5 ile birlikte artık mobil cihaz uygulama geliştiricileri bu platform üzerinde geliştiriyor oldukları uygumalarda “belirli sınırlar” içerisinde LINQ (Language Integrated Query) olarak ifade edilen altyapı ile “doğal yollarla” ellerindeki kaynakları sorgulayabilmektedirler. Bu bağlamda .Net Framework üzerinde LINQ üzerine onlarca farklı provider geliştirilmiş ve halen de geliştirilmeye devam edilmektedir.
Daha önce de ifade ettiğimiz üzere .Net Compact Framework üzerinde LINQ aşağıdaki sınırlar çerçevesinde desteklenmektedir ;
- Standart Query Operators
- Linq To Dataset
- Linq To XML
Bu yazımızda Linq To Dataset tarafındaki altyapıyı inceleyecek, LINQ ile mobil cihaz uygulamaları geliştirirken Dataset, DataTable ve DataRow’ lar üzerinde sorgulama işlemlerinin nasıl gerçekleştirileceğini örneklendireceğiz.
Dataset – DataTable – DataColumn - DataRow
Bilindiği üzere başlıkta yazan temel 4 kavram Ado.Net Disconnected (Bağlantısız) mimarinin temel yapı taşları olmaktadır. Bu noktada hedef herhangi bir x veri kaynağından gelen relational (ilişkisek) verilerin memory üzerinde konumlandırılması, ve verilerin herhangi bir t anında manipule (Add, Delete, Modify) edilmesi ve tekrardan merkezi verikaynağına gönderilmesi ise Ado.Net üzerinde tanımlı olan sınıflar (xxxDataAdapter, xxxDataReader, xxxCommand, xxxConnection v.b.) vasıtasıyla verilerin çekilmesi ve bu verilerin “memory üzerindeki veritabanımız” olarak kabaca ifade edebileceğimiz DataSet’ ler içerisinde oluşturduğumuz DataTable’ lara yüklememiz gerekmektedir.
DataSet genel olarak aşağıdaki hiyeraşri ile oluşturulmaktadır.
Resimden de anlaşılabileceği üzere DataSet provider bağımsız bir veri saklama, yönetme v.b. otamıdır. Siz DataSet’ in verilerini herhangi x bir veri kaynağı üzerinden çekebileceğiniz gibi örneğin bir web servis ya da bir WCF servis çağrısı sonucunda gelen XML üzerinden de yükleyebilmektesiniz. Genel olarak DataSet bir Container görevi görmekte, veriler DataSet içerisindeki DataTable’ lar üzerinde konumlandırılmaktadır. DataTable ise DataColumn (Sütunlar) ve DataRow (Satırlar) koleksiyonlarından oluşmaktadır. Ayrıca bu DataTable ‘ lar arasında DataSet seviyesinde DataRelation (İlişkiler) konumlandırarak ilintili kayıtlar arasında dolaşabilekteyizdolaşabilmekteyiz.
Bu noktaya kadar kısa bir DataSet – DataTable – DataColumn – DataRow kavramları hakkında bilgi sahibi olduk. Sıra geldi yazımızın asıl konusuna.
Normalde şartlarda DataTable üzerindeki bir verinin sorgulanması “çok sınırlı” olarak sınıf üzerindeki Select fonksiyonu ya da bu DataTable üzerinden oluşturulan bir DataView objesinin Filter özelliği vasıtasıyla “belirli sınırlar içerisinde” gerçekleştirilebilmektedir. Bu noktada daha kapsamlı bir sorgulama altyapısının olması, en azından halihazırda kullanıyor olduğumuz sql-tipi sorgulama altyapısının uygulanabilir olması uygulama geliştiricilere ciddi avantajlar kazandıracaktır.
Linq To Dataset bize bu altyapıyı sunmaktadır. .net Compact Framework 3.5 ile birlikte gelen System.Data ve System.Data.DataSetExtensions referanslarının projeye eklenmesinin sonusunda DataTable, DataRow ve DataView sınıfları içerisinde bu sorgulamaya altyapı sağlayacak konu ile ilgili birkaç Linq Extension Method’ u gelmektedir.
IntelliSense üzerinden DataTable’ a baktığımızda ise ;
İki adet çok kritik extension method gelmektedir. AsDataView Extension Method’ u DataTable üzerinden direk DataView oluşturmaya, AsEnumerable extension method’ u ise tablo içerisindeki DataRow’ ların içerisinde bulunduğu “içi dolu” bir EnumerableRowCollection

İşte tanıdığımız bir sürü extension method !
Bu noktada birkaç detayı daha netleştirelim. Bilindiği üzere DataSet’ ler “hazırlanışlarına göre” 2 farklı şekilde olabilmektedir ; typed ve untyped.
Typed DataSet’ ler “genellikle” bir code-generator tarafından oluşturulan ve içeriğine “daha hakim olabileceğimiz” cinsten DataSet’ lerdir. Örneğin, DataSet içerisinde 2 adet DataTable oluşturulduğunu varsayalım ; Employees ve Orders. Bu tablolara standart olarak ;
ulaşabilmekteyiz. Typed olan bir DataSet içerisindeki structure, veri kaynağına bakarak hazırlanacağından, yukarıdaki yönteme “alternatif” olarak şu şekilde de ulaşabileceğimiz bir model “code generetor” tarafından oluşturulmaktadır ;

Bu yöntem “eğer uygulanabiliyorsa” ciddi bir avantaj oluşturmakta, DataSet’ in yapısını anlamamıza ve işlem yapmamıza çok daha fazla olanak sağlamaktadır.
Genel olarak Linq To Dataset ile Typed ve UnTyped DataSet’ ler üzerinde sorgulama ya da filtreleme işlemleri gerçekleştirebilmektesiniz.
Gelelim uygulama örneklerine. Örneğimizde hem Typed hem Untyped DataSet’ ler kullanarak Linq To Dataset kod blokları geliştireceğiz. Bu noktada Typed DataSet’ i Northwind’ in Sql Server Compact Edition için hazırlanmış örnek veritabanı üzerinden “otomatik” olarak oluşturacağız.
Projemize bu örnek veritabanını ;
Patikası üzerinden ekliyoruz ; ve ekrana gelen Typed Dataset oluşturma sihirbazından Orders ve Employees Tablolarını seçiyoruz. İşlem sonucunda aşağıdaki şemaya sahip bir DataSet’ in projemiz içerisinde oluşturulmuş olması gerekmektedir.
Ayrıca, verilerin doldurulabilmesi adına her DataTable ile ilişkili TableAdapter’ ler ise otomatik olarak eklenmiştir.
Sıra geldi bu verileri sorgulamaya. Linq To Dataset içerisinde Standart Query Operators olarak ifade edilen operatörleri kullanabilmektesiniz. Sorgulama hem query expression yöntemiyle hem de extension method’ lar ile gerçekleştirilebilmektedir.
Uygulamamızın yüklenmesiyle birlikte veritabanı üzerinden Employees ve Orders tablolarını dolduruyoruz.
Ve sorgulamaya başlıyoruz. İlk örneğimizde Employees DataTable’ ı içerisinde EmployeeId değeri 5’ ten büyük olan DataRow’ ları seçelim ve Firstname değerlerine göre tersten sıralatalım.
Uygulama çalıştırılıp Button’ a basıldığında ise ;
Yukarıdaki sonuç kümesi elde edilmektedir. Id’ si 5’ ten büyük olan personellerin Firstname’ e göre tersten göre sıralanmış hali.
Bu noktada kod bloğunu biraz açıklamamız gerekmektedir.
Öncelikle dikkat edilirse sorgulama modeli Linq To Dataset’ te en ufak bir farklılık taşımamaktadır. Standart Query Expression modeli ile birebir aynıdır. Bu noktada dikkat çeken 2 adet nokta bulunmaktadır. Bunlardan ilki “r” sembolik adıyla anlık olarak temsil edilen DataRow sınıfı içerisinde normal şartlarda olmayan bir extension method’ un olmasıdır ; Field
Bu method, aranan kolon değerini, kendisine gönderilen kolon ismi üzerinden arayarak
Kod bloğunu incelemeye devam ediyoruz. Sorgu sonucunda elimize OrderedEnumerableRowCollection
Bu noktada hem IList noktasında hem de bir sonraki aşamada filtreleme yapabilmek adına en mantıklı çözüm DataView olmaktadır. Linq To Dataset paketi içerisinde gelen Extension Method AsDataView
Farklı bir örnek üzerinde çalışalım. Bilindiği üzere ilişkili tablolar sql tarafında Join sorguları ile ortaklaşa sorgulanabilmekte, birden fazla tablo üzerinden alınan veriler birleştirilebilmektedir.
Linq To Data üzerinde de join sorguları gerçekleştirebilmektesiniz ! Örneğimizde Orders tablosu ile Employees tablosu arasında Employee Id alanı üzerinden bir ilişki bulunmaktadır.
Hedefimiz ; Orders tablosundan satış bilgilerini almak ve bunun yanında Employee Id yerine bu satış ile ilişkili personelin Ad – Soyad (Firstname + Lastname) bilgilerini almaktır. Her iki tabloyu Load’ ta doldurduktan sonra aşağıdaki sorguyu çalıştırıyoruz :
Bu noktada sonuç kümesinin DataRow’ lardan oluşmamasından ötürü sonuç kümesini DataView’ e dönüştürememekteyiz. Fakat DataGrid IList implemantasyonunu sağlayan List
Peki, şu ana kadar tüm bu örnekleri Typed DataSet’ e uygun olarak hazırladık. Ya elimizde structure’ ı hakkında bu şekilde çalışamayacağımız, untyped bir DataSet olsaydı ? Yukarıdaki sorguyu UnTyped DataSet’ e uygun olarak tekrar yazıyoruz ;

Yukarıdaki kod bloğu dikkatlice incelenirse bir önceki kod bloğu ile arasında hem farklar hem de benzerlikler olduğu rahatlıkla anlaşılabilecektir. Gelelim farklılıklara ;
Bir önceki kod bloğunda TypedDataTable olarak DataSet’ in Employees özelliği üzerinden DataTable’ a direk ulaşıyor, join uygulayabiliyorduk. Bu noktada DataTable normalin dışında System.Data.TypedTableBase
Bunun dışında alanlara direk “özellikler üzerinden” ulaşamamakta (Örn : Employees.Employee_ID), DataRow içerisinde bulunan Field
İşte bu kadar !
Bütün bunların dışında gelen sorgu sonucu üzerinde diğer extension methodları kullanarak (sum, count v.b.) birçok işlemi gerçekleştirebilmektesiniz.
Bu yazımızda genel olarak Linq To Dataset kavramına değindik. Örnek uygulamayı sisteme aktardıktan sonra buradan yayınlayacağım. Bir başka yazıda görüşmek dileğiyle.
Devamını Oku...












