Makale Özeti

Sıfırdan yüze Linq...

Makale

1) Linq amaç

Linq ile hedeflenen geliştiriciler için veri erişimini kolaylaştıraçak C# diline entegre olacak ve veri sorgulama yeteneklerine sahip bir araça sahip olmaktır. C#/VB.Net gibi tip bağımlığı olan bir dilin veri sorgulama yeteneklerine sahip olması yeni bir fikir. Tipik olarak veri erişiminde bazı programatik zorluklar vardır. Eğer C# diline veri sorgulama yetenekleri kazandırmak istiyorsak aşağıdaki sorunları çözmeliyiz.

  • Farklı veri tipleri: Veri tabanlarında nvarchar, datetime, money, bit gibi veri tipleri CLR'da tanımlı decimal, int gibi veri tipleri ile eşleşmeleri gerekmektedir. Genelde alt seviyede "sihirli" ADO.NET çağrıları ile veri tabanındaki tiplerinden CLR veri tiplerine veri çekeriz..
  • Farklı veri kaynakaları: Veri kaynağımız bir XML dokümanı olabileceği gibi bir web servis mesajı veya bir veri tabanı olabilir.
  • Hiyerarşiler ile ilişkisel verileri sağlamak: Veri tabanları nesneleri normalizasyon kurallarını göz önüne alarak ilişkisel olarak diyan edilirler. Fakat C# uygulamalarında veri yapıları katılım/hiyerarşi kullanılarak diyazn edilir.  İlişkisel veri yapılarının CLR tarafından kullanılabiliecek hişyerarşik yapılara dönebilmesi gerekmektedir. ORM araçlarının temel çıkış noktası domain objeleri ve db arasındaki bu dizayn farklılığını gidermektir.
  • Veri erişimi için Intellisense ve dil desteği: Veri sorgulama metotlarını ve veri yapısının intellisense ile erişebilir olması gerekmektedir. Örneğim bir XML nesnesinin veri yapısı değişdiği algılanabilmeli ve intellisense ile gösterilebilmelidir.

Linq hedefine ulaşmak için C# diline veri sorgulama yetenekleri kazandırmak için sadece programatik zorlukları aşmak yetmiyor. Ayrıca mevcut durumda olan veri erişim tekniklerine göre daha iyi bir çözüm sunulmalıdır. Mevcutta olan veri manipülasyonu nasıl yapıldığını ve Linq ile önerilen yeni tekniği ve programatik zorlukların nasıl aşıldığını inceleyelim.

2) Veri manipülasyonu

Genellikle veri manüpülasyonunda hangi araçları veya API'leri kullanacağamıza veri kaynağımız karar verir. Hangi veri kaynağını kullanıyorsa o veri kaynağına özel olarak geliştirilmiş araçlar veya API'ler kullanmak zorunda kalırız. API'ler veri kaynağına ait veri yapılarıları ilişkileri ve hiyararişileri anlar ve bize geliştirme yapacak bir yol sunarlar. Geliştiriciler hangi veri kaynağı ile hangi API'yi kullanılacağını bilmek durumundalardır. Genelde veri kaynaklarımız objelerle, ilişkisel veriler veya xml veriler olur.

 

 

Obje veri kaynakları ile çalışırken List<T>,Dictionary<T> gibi generic yapıları kullanırız. Obje veri kaynağımız üzerinde quick sort, binary search gibi algoritmalarla sorgulama ve manipülasyon işlemlerini gerçekleştiririz. İlişkisel veri kaynağında veri sorgulamak için ADO.NET ile gelen  SqlDataReader, DataSet, DataTable gibi sınıfları kullanırız. ADO.NET ile gelen nesneler veri tabanındaki veri ilişkisini anlamakta ve bizim istediğimiz veri uygun hiyararşide getirmetedir. XML veri kaynağında XmlDocument ile xml veriyi alır ve XmlReader, Stream gibi nesneleri kullanarak XPath ile veri sorgulama işlemini yaparız. XML veriyi yapısal bir veriye cevirmek için XSLT kullanırız.Bu örnekleri çoğaltabiliriz.

Veri sorgulamada problem her veri kaynağı için farklı API'lerin kullanılması ve her veri tipi için farklı bir notasyon ile veri erişimimizi sağlanmasıdır. Her veri erişiminde farklı API'leri anlamak farklı yöntemler kullanmak zorunda kalırız. Linq durumunda ise tüm bu farklı veri kaynakları için tek bir veri erişim API'sini öğrenmek yeterlidir. Tüm veri kaynaklarını aynı şekilde bağlanır aynı şekilde sorgular ve aynı şekilde veri manipülasyonunu gerçekleştiririz. List<T> veri kaynağında kullanığınız kodu değiştirmeden XML veri kaynağında kullanabilirsiniz. Farklı veri kaynakları ile çalışmak için farklı API'lere ihtiyacınız kalmıyor.

3) Standart veri sorgulama işlemi

Linq System.Linq isim uzayında tanımlı bir API'dır. System.Linq üzerinde beş temel operasyonu içeren imlementasyonlar mevcuttur. Linq metotları tüm IEnumerable<T> nesneleri üzerinde çalışabilmektedir. IEnumerable<T> bir nesne kümesini taşıyan ve foreach döngüsünü destekleyen en temel implementasyondur. Ayrıca Linq operasyonları VS editorü tarafından tanınmaktadır. Kodlama anında İntellisense'den faydalanabilirsiniz. Yani Linq CLS uyumludur.

string[] names = new[]{ "Emre", "Ahmet", "Mehmet", "Asli" };
IEnumerable<string> query =    
          from n in names    
          where n.Length == 4    
          orderby n descending    
          select n;
foreach (var name in query) { Console.WriteLine(name); }

 

Buradaki örnekte dört karakter uzunluğundaki isimleri arıyoruz. Obje veri kaynağımız olan "names" değişkeni üzerinde Linq sorgumuzu oluşturuyoruz.  Linq sorgumuzda standart olan Where, OrderBy ve Select operasyonlarını yapıyoruz. Sorgu sonuçu IEnumerable<string> olarak foreach ile ekrana basıyoruz. İlk bakışta Linq sorgusu SQL sorgu yapısının testten yazılmış hali gibi görünmektedir. Linq ifadeleri neden bu şekildedir?

4) Linq sorgu ifadeleri

Linq ile obje dizisi, XML verisi veya veri tabanı üzerinde aynı sorgu ifadeleri ile çalışırız. Linq sorgu ifadeleri elliden fazla operator içermektedir. Bu geniş operator kümesi altı kategoride toplanmaktadır.

  1. Filtering: Where operatorleri ile veri kayanığındaki belirli bir şarta ait verilerin getirilmesi.
  2. Projection: Select operatorleri ile istenilen yapıda verilerin getirilmesi
  3. Joining: Join operatorleri ile veri yapıları arasında ilişki kurabilme
  4. Partitioning: Skip ve Take operatorleri ile veriyi isitenilen şekilde parçalara ayırabilme
  5. Ordering: OrderBy operatorleri ile veriyi sıralayabilme
  6. Aggregation: GroupBy operatorleri ile ortalma, toplam gibi grup operasyonları yapabilme

Tüm bu operatorler SQL ile aynı isimlendirme ile kullanılmıştır. Böylece kullanıcı alışkanlığı değerlendirilmiştir. Linq ile SQL'dekine benzer şekilde Select, From, Where, OrderBy, GroupBy operatorleri kullanılır.

Linq ile amaçlanının programlama dilinden ve araçtan bağımsız veri işlemlerini gerçekleştirmek olduğunu görmüştük. Peki bu kadar geniş bir operator kümesi ile dil ve araçtan bağımsız veri sorgulama nasıl yapılabilinir? Aynı sorgu ifadelerini .NET içinde her yerde kullanabilmek için .NET neleri sağlamalıdır?

Programlama dillerinden ve araçlardan bağımsız sorgu ifadeleri yazılabilmesi için Linq üç temel desteği yerine getirmektedir.

  1. Metadata: Linq sorgu içindeki veri yapılarını bizim için üretmektedir.Bizde metadata verilerini kullanarak Linq operatorlerini genişletebiliriz.
  2. Statik tip kontrolü: Linq ile yazılan sorgunun doğru veri yapıları ile yazıldığını kodlama anında öğrenebiliriz. Yanlış tip atamalarında derleyici bizi uyaracaktır.
  3. Intellisense: Linq ile birlikte intellisense özelliği kullanılabilmektedir.

Örneğim bir önceki başlıkta yazdığımız Linq sorgusunda dört karakterli isimlerin yerine isimlerin uzunluklarını dönersek ne olur? Linq metadata'dan yanlış bir tip dönüşümü yaptığımızı anlar ve compiler bizi uyarır.

Yukarıdaki örnekte IEnumerable<string> değişkenine IEnumerable<int> değeri atanmaya çalışılmıştır. Compiler bizi yanlış tip kullanıldığına dair uyarmaktadır. Ayrıca kodlama anında intellisense'de çalışyor ve bize n değişkeninin elemanlarını göstermektedir.

Linq görevini yerine getirebilmek için önce metadata'yı elde etmelidir. Bu sebebden dolayı SQL'in tersine Linq ifadelerinde önce "from" cümleciği ile metadata/veri yapısı gösterilmektedir. Daha sonra Linq statik tip kontrolleri ve intellisense desteğini sağlamaktadır. SQL 'in tersine Linq sorgu ifadelerinde, önce sorguya kaynak olan veri yapıları bulunmalı en son sorgu sonucu olacak veri yapısı verilmelidir.

4) Linq genişletilebilirlik

Linq genişletilebilr bir mimariye sahiptir. Linq üç noktada genişleme desteği sunmaktadır.

  1. Kendi sorgu operatorlerinizi yazabilirsiniz. Örneğim hesaplama işlemlerinde sıklıkla kullanılan Sigma ve Pi fonksiyonları için kendinize ait bir Linq operatorü yazabilirsiniz.
  2. Mevcut operatorleride ihtiyaçlarınıza göre genişletebilirsiniz. Örneğim kendi veri tibiniz için özelleşmiş Select operatorü yazabilirsiniz.
  3. Linq provider ile Linq genişletilebilmektedir. Sorgulanabilen tipler ile Linq operatorleri arasınra gateway görevi gören provider'lar mevcuttur. Kendi veri kaynağınızın nasıl kullanılacağınız açıklayan Linq providerınızı yazıp Linq desteği sağlayabilirsiniz. PLinq (Paralel Linq), Linq to Ldap, Linq to Flickr, Linq to Amazor gibi çeşitli Linq provider'ları mevcuttur.

5) Linq to objects

Hafızada yer alan nesneler üzerinde yapılan foreach gibi döngü kodlarını Linq ifadeleri şeklinde yazabiliriz. Döngü ifadeleri için çok fazla kod yazmaktayız. Linq to objects ile bu kod karmaşasını şık bir çözüm geliyor. Bir reflection örneği ile açıklayalım. Örneğim mevcut assembly üzerindeki public tiplerin isimlerini elde etmek istiyoruz. Mevcut assembly üzerindeki tüm tipleri bulur sonra foreach ile public tipleri belirler ve en son isimleri bir List<string> üzerine ekleriz. Aynı problemi Linq to object ile aşağıdaki gibi çözebiliriz.

IEnumerable<string> publicTypes =    
           from t in Assembly.GetExecutingAssembly().GetTypes()    
           where t.IsPublic    
           select t.Name;
foreach (var name in publicTypes) { Console.WriteLine(name); }

6) Ertelenmiş yürütme

Linq konseptinin en önemli parçalarından biride yürütme işlemidir. Oluşturduğumuz sorgu ne zaman çalışır? Ne zaman veri kaynağına erişim yapılır? Sorgu ifadeleri sorgu sonuçuna erişim olmadıkça çalışmazlar.  Bir önceki sorguyu ele alırsak foreach içinde sorgu sonuçuna erişim sağlanıncaya kadar sorgu bir metadata ifadesi olarak saklanmaktadır. Sorgu sonuçuna ilk erişim anında sorgu ifadesi çalıştırılmaktadır. Ertelenmiş yürütmemin sebebi gevşek/lazy operatorlerin sorguda kullanılmış olmasıdır. Bir önceki örnekte kullanılan From,Where, Select operatorleri gevşek/lazy operatorlerdir. Çalışma anında doğrudan sonuçu hesaplayan Count, ToList gibi sıkı/tigth operatorlerde mevcuttur.

Ertelenmiş yürütme sayesinde genel bir sorguyu servis tarafında oluşturur ve önyüzde filitreleyebiliriz. Böylelikle ertelenmiş yürütme bize composite/birleştirilmiş sorgular oluşturmamızı sağlamaktadır. Bu yetenek DAL için son derece önemlidir. Bir çok iş uygulamasında sorgunun filitre kısmı önyüzde sorgu kaynağı ve veri yapısıda sunucuda bulunmaktadır.

Bu önemli özelliği anlamak için aşağıdaki sorguyu inceleyelim. Bu örnekte bir sorgu oluşturuyoruz ve sorgu sonucuna erişim yapmadan veri kaynağımıza yeni bir kayıt ekleniyor. Sonuç olarak ne görmeyi beklersiniz? Sorgu anında ki kayıtları mı? Erişim anındaki kayıtları mı?

public class Kisi 
{    
     public string Ad { get ; set ; }    
     public int Yas { get ; set ; }
}
static void Main(string [] args){    
    var kisiler = new List <Kisi >{        
        new Kisi { Ad = "Ahmet" , Yas = 17 },
        new Kisi { Ad = "Mehmet" , Yas = 18 },
        new Kisi { Ad = "Ayşe" , Yas = 25 }    };
    
    var ehliyetAlabilecekKisiler = kisiler.Where(k => k.Yas > 18);    
    
    kisiler.Add(new Kisi { Ad = "Emre" , Yas = 30 });        
    var sonuc = ehliyetAlabilecekKisiler.Select(c => c.Ad).ToList();    

foreach (var kisi in sonuc)    {        Console .WriteLine(kisi);    }}

Yukarıdaki örnekte sonuc değişkenin değerinin ne olmasını beklersiniz? Sonradan eklenen kayıt sorgu sonucunda gelecek midir?

Sorgunun çalışma anında elde edilen sonuç:

sonuc
Count = 2
    [0]: "Ayşe"
    [1]: "Emre"

Örnekte görüldüğü üzere Linq ifadesi veri olarak sorgu sonuçunu değil sorgunun kendisini saklamaktadır. Böylelikle veri erişimi sorgunun çalıştığı anda yapılmakta ve en güncel sonuç getirilmektedir.

7) Linq to Xml

Bir diğer .Net Linq teknolojisi Linq To Xml'dir. Linq to XML sadece mevcut XML API'lerin yanına gelmiş olan yeni bir XML API değildir. Genellikle yazılım geliştiricilerin Linq To XML başlığını duydukalarında verdikleri ilk tepki: Hayır öğrenilmesi gereken yeni bir  XML API !

XML veri işlemek durumunda kalanlar System.Xml isim uzayındaki XmlDocument, XmlElement gibi sınıfları kullanarak bir belirli bir işlem sırasını takip etmek zorunda olan aşağı doğru uzayıp giden okunabilirlikten uzak kod blokları ile çalışmıştır.

Linq To XML ile XML'in kendi formal yapısına uygun daha geliştirici dostu sabit ve daha hafifi bir API sunulmaktadır. Linq To XML benzer şekilde Xml doküman için XDocument, Xml attribute, ve node için XElement sınıflarını sunmaktadır.

 

System.Linq.Xml isim uzayının anahtar sınıfı XElement'tir. Bir çok gelişmiş kolay kullanım özelliğine sahiptir. Örneğim fonksiyonlar ile XML üretimini ele alalım:

XElement arabaUreticiler =     
    new XElement("Ureticiler",
         new XElement("Uretici", "Honda"),
         new XElement("Uretici", "Kia"),
         new XElement("Uretici", "Toyota"),
         new XElement("Uretici", "BMW"));

var xml = arabaUreticiler.ToString();
<Ureticiler>
     <Uretici>Honda</Uretici>
     <Uretici>Kia</Uretici>
     <Uretici>Toyota</Uretici>     <Uretici>BMW</Uretici> </Ureticiler>
  

Yukarıdaki örnekte gayet özlü ve okunabilir XML üretimi sağlanmaktadır. XElement üretip her hangi bir yerde saklamadan iç içe metot çağrıları ile XML üretimi yapılabilmektedir. XElement constructer içinde ilgili node'un adını ve params olarak alt node verisini alabilmektedir. Bir başka XElement constructer'ı params string olarak XML elementin node adını ve değer çiftini alabilmektedir. Böylelikle son derece okunaklı bir XML üretimi sağlanmaktadır.

Fonksiyonel XML üretimi

XElement Linq sorgularıda ilede yapabilirsiniz. Böylelikle sorguyu ve XML veriyi ayrı ayrı oluşturmak zorunda kalmayacağız. Örneğim bilgisayarımızda çalışan tüm process'lerin listesini XML doküman olarak elde etmek istiyoruz.

XDocument islemler =
     new XDocument(
        new XElement("Islemler",
             from p in Process.GetProcesses()
             orderby p.ProcessName  ascending
             select new XElement("Islem",
                 new XAttribute("Ad", p.ProcessName),
                 new XAttribute("No", p.Id))));
<Islemler>
     <Islem Ad="AiChargerAP" No="3444" />
     <Islem Ad="AppleMobileDeviceService" No="1508" />
     <Islem Ad="audiodg" No="440" />
     <Islem Ad="ConsoleApplication1.vshost" No="1788" />
     <Islem Ad="devenv" No="6048" />
     <Islem Ad="distnoted" No="2544" />
     <Islem Ad="dllhost" No="4968" />
     <Islem Ad="dwm" No="1744" />
     <Islem Ad="explorer" No="1884" />
         ....... 
</Islemler>

Sadece bir kaç satır kod ile Linq To XML API yardımı ile iç içe fonksiy çağrıları kullanarak XML üretimini gerçekleştirdik.

XML Sorgulama

Bir önceki örnekte oluşturduğumuz XML dokümanı içinde devenv işlem nolarını bulan sorguyu oluşturalım.

IEnumerable<int> islemNolari =
     from e in islemler.Descendants("Islem")
     where e.Attribute("Ad").Value == "devenv"
     orderby (int)e.Attribute("No")
     ascending select (int)e.Attribute("No");

Doküman üzerinde tüm XElement'lerin üzerinde Descendants metodu ile arama yapabilmekteyiz. Yukarıdaki sorguda dokümanda yer alan tüm "Islem" node'ları üzerinde "Ad" attribute değeri "devenv" olan XElement'leri bulduk. "No" XAttribute değerini doğrudan int'te cast ederek kullandık.

Görüldüğü gibi Linq To XML sadece bir XML API değildir. Linq To XML son derece programcı dostu ve kolay kullanıma sahip XML verisi üzerinde kolay üretim ve sorgulamayı destekleyen XElement anahtar sınıfı üzerine kurulu güçlü ve basit bir API'dır.

8) Linq To SQL

Linq To SQL SQL Server için geliştirilen Linq sorgu ifadelerini TSQL komutlarına çevirebilen, domain objelerini veri tabanı nesnelerine çevirebilen basit bir ORM aracıdır. Lin to SQL sadece SQL Server ile çalışabilmektedir. SQL Server Ce / 2000 / 2005 / 2008 / 2012 versiyonlarını desteklemektedir. Oracle, Db2 gibi diğer veri tabanları ile çalışmamaktadır.

from p in Pages
where p.IsPublish && p.Published > DateTime.Noworderby p.Title
select new { p.Title, p.Slug }

Linq ifadesindeki context sınıfı özel bir sınıftır. Context sınıfı veri tabanı ve domain arasında gateway görevi görmektedir. Context sınıfı veri tabandaki tabloları property olarak sunmaktadır. Yukarıdaki sorgu örneğinde Context sınıfı Pages property'si ile Pages tablosuna erişilmektedir. p değişkeni ilede Pages tablosundaki kolonlara erişilebilmektedir. Yukarıdaki sorgu örneğimizde de where/from/select/orderby gibi aynı Linq operatorlerini kullanıyoruz. Yayınlanmış olan sayfaların isim ve adreslerini aradığımız Linq sorgu ifademizin Linq To SQL ile üretilmiş TSQL çıktısı şu şekilde oluşmaktadır:

SELECT [t0].[Title], [t0].[Slug]
FROM [Pages] AS [t0]
WHERE ([t0].[IsPublish] = 1) AND ([t0].[Published] > @p0)
ORDER BY [t0].[Title]

Bir örnekte Linq To SQL nasıl çaılışıyor izleyelim. EcBlog veri tabanı için bir dbml dosyası oluşturdum. Page,Tag ve TagPage tablolarını sürükle bırak ile dbml dosyasına ekledim. Burada tablolar arasındaki ilişkiyi görmeniz mümkün. Ayrıca Context sınıfında yer alan elemanların özelliklerini bu editor ile değiştirebilirsiniz.

 

Objeler ve Tablolar Arasında Eşleştirme

Linq To SQL veri tabanı tablolarını domain objeleri olarak gösterme sihrini nasıl yapmaktadır? Tüm bu sihirin arkasında veri tabanı tabloları ve domain objeleri arasındaki eşleştirme yatmaktadır. Linq To SQL veri tabanındaki tabloları 1:1 olarak domain objeleri ile eşleştirmektedir. Bu eşleşme iki şekilde yapılabilmetedir. Birinci yol domain objelerine attribute'ler vermektir. EcBlog örneğimizdeki eşleştirmeler için üretilen kodu incelediğimizde attribute'ler ile yapılan eşletirmeyi görmemiz mümkün.

[global::System.Data.Linq.Mapping.DatabaseAttribute(Name="ecblog")]
public partial class EcBlogDataContext : System.Data.Linq.DataContext{

   [global::System.Data.Linq.Mapping.TableAttribute(Name="dbo.Pages")]
   public partial class Page : INotifyPropertyChanging, INotifyPropertyChanged {

        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_PageId",
             AutoSync=AutoSync.OnInsert, DbType="BigInt NOT NULL IDENTITY",
             IsPrimaryKey=true, IsDbGenerated=true)]
        public long PageId {
        
        [global::System.Data.Linq.Mapping.ColumnAttribute(Storage="_Title",
             DbType="NVarChar(500) NOT NULL", CanBeNull=false)]
         public string Title {

Veri tabanındaki tablolar Table attribute ile işaretlenmiş durumdadır. Tabloların eşleştirme için veri tabanı isimleride verilmiş. Benzer şekilde kolonlarda column attribute ile işaretlenmiş durumdadır. Column attribute ile property'nin veri tabananındaki ismini, veri yapısı, null olup olmayacağı gibi veri tabanına özel değerleri verebilirsiniz.

 

Eşleştrime yapmak için ikinci yol harici bir xml dosyasını vermektir. Dizaynıra bağlı kalmadan kendi eşleştirmenizide xml dosyası ile yapabilirsiniz.Bu yöntem hakkında daha fazla bilgiyi msdn'de bulabilirsiniz.

<Table Name="dbo.Pages" Member="Pages">
  <Type Name="Pages">
    <Column Name="PageId" Member="PageId"/>
    <Column Name="Title" Member="Title"/>
    <Column Name="Slug" Member="Slug"/>
    <Column Name="ContentHtml" Member="ContentHtml"/>
  </Type>
</Table>

Bu eşleştirmelerin amacı DataContext sınıfını oluşturabilmektir. EcBlogDataContext sınıfı Pages ve Tags tabloları için Insert/Update/Delete metotları sağlamaktadır. DataContext sınıfından gelen bir çok özellikte mevcuttur. DataContext.Log property'si ile Veri tabanında yapılan tüm işlemleri loglayabilirsiniz. Yeni bir log sınıfı oluşturup Log property'sine set etmeniz yeterlidir. Benzer şekilde DataContext.Transaction ile arkada çalışan DTC desteğini kullanarak dağınık transaction işlemlerini yapabilirsiniz. DataContext.CreateDatabase ile veri tabanını kurabilirsiniz. Test kodu yazarken CreateDatabase çok işinize yarıyacaktır. Veri tabanında komut çalıştırabileceğiniz Execute* metotları mevcuttur. Execute* metotları objeler ve tablolar arasındaki eşleştirmeler kullanarak çalıştırılmaktatır.

 

9) Entity Framework

 

Entity framework ve Linq To SQL birbirine çok benzer teknolojilerdir. Entity framework daha geniş bir hizmet sunmaktadır. Temel olarak dört bileşeni vardır.

  1. Linq To Entities: Entity framework ile çalışan Linq To Enitities provider'ı Linq To SQL'e benzer şekilde Metadatalardan faydalanmaktadır. Üretilen Sql kodu Entity SQL olarak anılanmakta ve tüm veri tabanları tarafından desteklenmektedir
  2. Change Tracking:  sorgu sonucu olarak alınan entity'ler üzerindeki değişimler ObjectContext ile takip edilmektedir. Daha sonra persist edilerek değişiklikler veri tabanına yazılmaklabilmektedir.
  3. Serialization: Entity framewok WCF DataContract  yapısınıda desteklemektedir. Böylelikle verinizi WCF servislerden ek efor gerektirmeden gecirebilmektesiniz.
  4. Transaction: Entity framewok DTC ile konuşarak dağınık transaction desteğinisalamaktadır.

Linq To SQL varken neden Entity Framework'e ihtiyaç duyuldu?

Çünkü Linq To SQL'de basit bir eşleştirme mekanizması kullanılarak 1:1 eşleşme sağlanmıştı. 1:1 eşleşme ile Linq To SQL fiziksel/store model veri yapısını desteklemektedir.

Linq To Entity kavramsal/lojik veri yapısını desteklemektedir. Kavramsa veri yapısını desteklemek için Entity framework üç kademeli bir veri erişim yolu izlemektedir.

  1. Fiziksel veri modeli katmanında Entity framework Linq To SQL'e benzer şekilde veriye ait metadata bilgisini tutmaktadır.
  2. Fiziksel veri modeli ile entity veri modeli arasında eşleştirme katmanı bulunmaktadır. Eşleştirme adımında Table Per Type (tip başına bir tablo) ve Table Per Hierarchy (hiyararşinin en altındaki tip için bir tablo) gibi iki farklı inheritance uygulanabilmektedir. Linq To Entities ile m:n eşleşme yapılabilmektedir. Yani bir tabloda birden çok entity veya bir entity'de birden çok tablo yer alabilmektedir. Bu özelliklerle birlikte entity veri modeli fiziksel veri modeli ile kısıtlanmadan geliştirilebilmektedir.
  3. En üst adımda kavramsal/lojik veri yapısı olan entity veri modeli (edm) bulunmaktadır. Kavramsal model bizim tanımladığımız veri sınıflarından oluşmaktadır. Linq To Entities kavramsal veri modeli ile çalışmaktadır. ObjectContext sınıfı kavramsal veri yapımızı için bir gateway görevi görmektedir.

10) Sonuç

Linq ile .Net platformu için yeni sorgulama kabiliyetleri gelmiştir.  IEnumarable<T> arayüzünü destekleyen tüm veri yapılarında standart Linq operatorleri ile çalışılabilinmektedir. Linq farklı veri kaynakları için genişletilebilmekdedir. Bu genişleme operator veya provider seviyesinde yapılabilmektedir. Linq To Xml ile .Net platformı için yeni bir XML Api sağlanmaktadır. XDocument ve XElement ile Xml veri yapısına uygun şekilde daha anlışılır Xml üretimi ve Xml kullanımı sağlanmaktadır. Veri tabanları kısmında Linq To Sql ve Linq To Entities ile birlikte ORM özellikleri sağlanmaktadır. Linq To Sql sadece Sql Server ile çalışabilmektedir. Linq To SQL ile fiziksel veri yapınızı domain içerisine taşıyabilirsiniz. Linq To Entities ile fiziksel ve kavramsal veri yapınız arasındaki farklılığı çözmek için daha fazla eşleştirme seçeneğine sahip olursunuz ve Linq To Entities ile tüm veri tabanlarını destekleyebilmektesiniz.

 

Emre Coşkun

www.emrecoskun.net