26 Nisan 2015 Pazar

Fluent NHibernate Automapping(Otomatik Eşleme)


    Herkese merhabalar.

   Bugün sizlere Fluent NHibernate'in sağlamış olduğu kolaylıklardan bir tanesi olan otomatik eşlemeden bahsedeceğim.  Büyük uygulamalarda modellerinizin eşleştirmelerini yapmak size oldukça sıkıcı gelebilir. Bu durumdan sizi kurtarmak üzere otomatik eşleştirme yardımınıza koşacak. Automapping kavramı; isimlendirme grupları kullanılarak gerçekleştirilen ve objelerinizi otomatik bir şekilde sınıflandıran mekanizmadır [1]. Otomatik eşleştirmede isimlendirme gruplarına(conventions) neden ihtiyaç duyuyoruz dediğinizi duyar gibiyim. Otomatik eşleştirme yaparken eğer convention sınıflarınızı default olarak kullanıyorsanız, otomatik eşleştirici eşleştirme yaparken örneğin; Id isimli integer tipindeki değişkeninizin otomatik olarak artış gösteren bir öncül anahtar(primary key) olduğunu anlaması gerekmektedir [2]. Aşağıdaki örnek ile otomatik eşleştirmenin yapılmasını sağlayan bazı kavramları öğreneceğiz.

 public class Yiyecek  
 {  
  public int Id { get; set; }  
  public virtual string Ad { get; set; }  
  public virtual decimal Fiyat { get; set; }  
 }  
 public class Buzdolabı  
 {  
  public virtual int Id { get; set; }  
  public virtual IList<Yiyecek> Yiyecekler { get; set; }  
 }  

Yukarıdaki kod ile one-to-many ilişkisi kurulmuştur. Bir buzdolabında birden fazla yiyecek bulunabilir. Otomatik eşleştirmemizi yapabilmemiz için Automap sınıfını, fluent konfigürasyon API kombinasyonu ile kullanmalıyız.

 AutoMap.AssemblyOf<T>  

Yukarıdaki kod parçası generic bir tip alan statik bir metottur. Otomatik eşleştirmenizi yapmak istediğiniz sınıfınızı T değişkeninin yerine yazmalısınız. İşte otomatik eşleştirme yapmak bu kadar kolay.  AutoMap.AssemblyOf<Yiyecek>  kodunu çağırdığınız zaman;  Yiyecek sınıfının tanımlandığı assembly'ye bağlanan AutoPersisteneceModel objesi üretilir [3]. Kullanacağımız SessionFactory'i yaratmak için aşağıdaki kod parçasını kullanmalıyız.

 var sessionFactory = Fluently.Configure()  
  .Database(/* database config */)  
  .Mappings(m =>  
   m.AutoMappings  
    .Add(AutoMap.AssemblyOf<Yiyecek>()))  
  .BuildSessionFactory();  

    Automapper, hangi sınıfın objeniz veya servisiniz olduğunu ayırt edemez. Bu yüzden ihtiyacımız olan final bir metot olan Where(Func)'i kullanmalıyız. Bu metot ile genellikle namespace sınırlaması konulur; ancak siz Type objesi ile istediğiniz sınırlamayı koyabilirsiniz [1]. Bu örnekte ben de namespace sınırlamasına ihtiyaç duyuyorum.


 var autoMappings = AutoPersistenceModel  
  .MapEntitiesFromAssemblyOf<Yiyecek>()  
  .Where(t => t.Namespace == "Mutfak.Entities");  
 var sessionFactory = new Configuration()  
  .AddProperty(ConnectionString, ApplicationConnectionString)  
  .AddAutoMappings(autoMappings)  
  .BuildSessionFactory();  

Yukarıdaki şekilde namespace sınırlamamızı koyduktan sonra otomatik eşleştirmemizi tamamlamış olduk. Gördüğünüz gibi yukarıdaki yapıyı kullanarak otomatik eşleştirme yapmak bu kadar basit.  Bu haftalık anlatacaklarım bu kadar. Bir sonraki hafta; isimlendirme sınıflarımızı kendimize göre nasıl uyarlayabileceğimizden bahseceğiz, hoşçakalın..

Kaynaklar


[1] Fluent NHibernate: Auto Mapping Introduction, http://www.jagregory.com/writings/fluent-nhibernate-auto-mapping-introduction/, Nisan 22, 2015.

[2]GETTING STARTED WITH FLUENT NHIBERNATE AND AUTO MAPPING IN C#, http://blog.json.codes/web-development/getting-started-with-fluent-nhibernate-and-auto-mapping-in-c/, Nisan 22, 2015.

[3] Auto mapping, https://github.com/jagregory/fluent-nhibernate/wiki/Auto-mapping, Nisan 23, 2015.

19 Nisan 2015 Pazar

Fluent NHibernate ile Kullanıcı Tanımlı Tipler Kullanmak



    Herkese merhabalar.


    Bugün sizlere, Fluent NHibernate kullanırken kullanıcı tanımlı tiplerin nasıl kullanıldığından bahsedeceğim. Kullanıcı tanımlı tip derken ne demek istediğimi enum(enumeration) kavramını açıklayarak ifade etmek istiyorum. Program içerisinde kullanılan sabitlerin anlamlandırılması ile sabitlere isim vererek bir grup altında toplayabiliriz. İşte bu gruplara enum(enumaretion) denmektedir. Enum içerisindeki elemanlar, dizilerdeki gibi 0 sıra numarasından başlamak üzere sıralanır [1]. Enum kullanımını daha iyi anlamamız açısından, enum denilince akla gelen klasik örneği sizlerle paylaşmak istiyorum.

   Örneğin; programımızda haftanın günlerini kullanmak isteyelim. Bu günler ile karmaşık işlemler yapmak isteyelim. Bunun için  her güne sayısal değer vermemiz bizim işimizi görecektir. Pazartesi, Salı, Çarşamba, Perşembe, Cuma, Cumartesi, ve Pazar’a 0,1,2,3,4,5 ve 6 tam sayı değerlerini tanımlamamız yeterli olacak ve bu tam sayılar üzerinden işlemlerimizi gerçekleştireceğiz. Öte yandan, sıfırı (0) kullandıktan ve bir süre sonra koda baktığımızda sıfırın Pazartesi gününü ifade ettiğini hatırlayamayabiliriz. Bu durumda, C# bizlere güzel bir çözüm sunar. Bu çözümde; değerlerin grup sembolik bir ad ile bildirilebileceği "enum" anahtar sözcüğü kullanılır [2]. Enumeration türünü aşağıdaki şekilde tanımlayabiliriz.

 Enum HaftaGunler  
 {  
 Pazartesi,  
 Sali,  
 Carsamba,  
 Persembe,  
 Cuma,  
 Cumartesi,  
 Pazar  
  }  

Enumeration türünü yukarıdaki şekilde tanımladıktan sonra aşağıdaki şekilde erişebiliriz.


 HaftaGunler gun = HaftaGunler.Pazar;  
 MessageBox.Show(gun.ToString());  

Böylelikle, mesaj kutumuzda "6" yazacaktır. Haftanın günlerinin hepsini birden almak istersek .GetNames() metodunu kullanırız. Bu metot yardımıyla enum içerisinde kullandığımız değerleri  string formatında bir dizide aşağıdaki şekilde kullanabiliriz [2].

  string[] gunler = Enum.GetNames(typeof(HaftaGunler));  

    Şimdi de enumların Fluent NHibernate'teki kullanımına bakalım. Fluent NHibernate ile özel bir kullanıcı tipi tanımlanmak istendiğinde, IUserType arayüzünden kalıtılmış bir sınıf ile ilgili tipi tanımlayabiliriz [3]. Aşağıdaki kod örneğinde, lisans ve yüksek lisans öğrenci tipini içeren enum kullanılmıştır [4].

 public enum Ogrencitipi  
 {  
   Lisans,  
   Yukseklisans  
 }  

 using System;  
 using System.Data;  
 using NHibernate.SqlTypes;  
 using NHibernate.UserTypes;  
 namespace YourNamespace.Persistence.Mappings.CustomTypes  
 {  
   public class OgrencitipiMap : IUserType  
   {  
     new public bool Equals(object x, object y)  
     {  
       return object.Equals(x, y);  
     }  
     public int GetHashCode(object x)  
     {  
       return x.GetHashCode();  
     }  
     public object NullSafeGet(IDataReader rs, string[] names, object owner)  
     {  
       object r = rs[names[0]];  
       var value = (string)r;  
       if (string.IsNullOrEmpty(value))  
         throw new Exception("Geçersiz!");  
       switch (value)  
       {  
         case "L":  
           return Ogrencitipi.Lisans;  
         case "Y":  
           return Ogrencitipi.Yukseklisans;  
         default:  
          throw new Exception("Geçersiz öğrenci tipi!");  
       }  
     }  
     public void NullSafeSet(IDbCommand cmd, object value, int index)  
     {  
       object paramVal = 0;  
       switch ((Ogrencitipi)value)  
       {  
         case Ogrencitipi.Lisans: paramVal =  
          "L"; break;  
       case Ogrencitipi.Yukseklisans: paramVal =  
          "Y"; break;  
         default:  
           throw new Exception("Geçersiz öğrenci tipi!");  
       }  
       var parameter = (IDataParameter)cmd.Parameters[index];  
       parameter.Value = paramVal;  
     }  
     public object DeepCopy(object value)  
     {  
       return value;  
     }  
     public object Replace(object original, object target, object owner)  
     {  
       return original;  
     }  
     public object Assemble(object cached, object owner)  
     {  
       return cached;  
     }  
     public object Disassemble(object value)  
     {  
       return value;  
     }  
     public SqlType[] SqlTypes  
     {  
       get { return new SqlType[] { new StringSqlType() }; }  
     }  
     public Type ReturnedType  
     {  
       get { return typeof(Ogrencitipi); }  
     }  
     public bool IsMutable  
     {  
       get { return false; }  
     }  
   }  
 }  

Mapping sınıfınızda aşağıdaki şekilde eşleştirmenizi yapabilirsiniz.

  //NHibernate 2.X  
   Map(x=>x.Ogrencitipi).CustomType<OgrencitipiMap>();  
   //NHibernate 3.X  
   Map(x=>x.Ogrencitipi).CustomTypeIs<OgrencitipiMap>();  

Yukarıdaki örnekte gördüğünüz gibi enum yapısını kullanarak istediğiniz verileri Fluent NHibernate projenizde kullanabilirsiniz. Enum kullanımının faydaları; kod okunabilirliğini arttırması, muhtemel değer kümesinin daraltılması ve tip güvenliğini sağlaması dolayısıyla hata payını en aza indirmesidir [5]. Böylelikle yeri geldiğinde projemizde enum kullanımının nasıl gerçekleşeceğini görmüş olduk.

    Umarım faydalı bir yazı olmuştur, hoşçakalın..

Kaynaklar


[1]C# ile Enum Kullanımı, http://sanalkurs.net/c-ile-enum-kullanimi-8423.html, Nisan 15, 2015.

[2]C# ve Enumeration (Enum) Kullanımı, http://emraheroglu.blogspot.com.tr/2010/01/c-ve-enumeration-enum-kullanm.html, Nisan 16, 2015.

[3]Fluent NHibernate ile kullanıcı tanımlı tipler kullanmak, http://b.zor.lu/fluent-nhibernate-ile-kullanici-tanimli-tipler-kullanmak/, Nisan 16, 2015.

[4]USING AN ENUM ON A FLUENTNHIBERNATE MAPPING [C#], http://crodrigues.com/using-a-enum-on-a-fluentnhibernate-mapping-c/, Nisan 17, 2015.

[5]Daha Okunabilir Kod ve Yaşanabilir Dünya İçin Enum’lar, http://kodcu.com/2014/08/okunabilir-kod-ve-enum/, Nisan 17, 2015.

11 Nisan 2015 Cumartesi

HQL (Hibernate Query Language)

Herkese merhabalar.

   Doğrudan SQL sorgularını kullanarak veritabanı üzerinde işlemler gerçekleştirmek istemiyorsanız; nesneler üzerinde işlem yaparak da veritabanı işlemlerinizi gerçekleştirebileceğiniz bir sorgu dili mevcut. Bugün sizlere Hibernate'in sorgu dilinden bahsetmek istiyorum. Hibernate sorgu dili, SQL'e benzer özellikleri olan nesne tabanlı bir sorgu dilidir. HQL'in SQL'den en önemli bilinmesi gereken farkı; SQL kolonlar ve tablolar üzerinde işlem yaparken, HQL objeler ve diğer özellikler üzerinde işlemlerini gerçekleştirir. HQL, Hibernate tarafından, veritabanı üzerinde doğrudan işlem gerçekleştirebilen SQL'e dönüştürülür. Şu unutulmamalıdır ki veritabanı ile en yakın olan katman her zaman SQL'dir [1]. 

   HQL yazarken büyük-küçük harf duyarlılığına dikkat edilmelidir. WHERE, SELECT, FROM gibi kelimeler de  büyük-küçük harf duyarlılığı aranmazken; tablo ve kolon isimleri gibi özellikler yazılırken büyük-küçük harf duyarlılığı mevcuttur. Şunu da eklemek istiyorum; HQL'in güzel özelliklerinden birisi de  veritabanından bağımsız yazılan bir sorgu dili olmasıdır [1].  Gelin hep birlikte HQL'de en çok kullanılan kalıplara bakalım.

from ve as 

 from obje [as nil_obje]*   
 obje_adi  
  
   Genellikle select ile kullanılır. Sorguda istenilen cevabın hangi tablodan çekileceğini belirtir. "as" ifadesi ile uzun ve kullanımı zor olan tablo veya alan adlarına geçici olarak kısa isimler vererek bunları kodlamamızda kullanabiliriz [2]. Böylece mevcut tablo yapımız bozulmadan dinamik olarak belirlediğimiz isimleri kullanabilmekteyiz.

select


Sorgunun sonuç kümesinde ne olacağını belirten sözcüktür [2].

 select ogrenciisim from bilgisayarMuhendisligi as bilgisayarogrencisi  


where


   Sorgu kümesinde dönmesi istenen durumların istenen koşullar doğrultusunda dönmesini sağlayan sözcüktür. =, >, AND, NOT  gibi operatörler kullanılır [2].

  select ogrenciisim from bilgisayarMuhendisligi as bilgisayarogrencisi where ogrenci_no > 10   

Birleşik Değerli Fonksiyonlar


   Birleşik değerli fonskiyonlar kullanılarak, yapılan sorgulama alanı daraltılarak çalışma süresi optimize edilebilir [2,3].

  • avg(): Ortalama değeri döndürür.
  • count(): İstenilen değere bağlı kayıt sayısını döndürür. Boş değer içeren kaydı saymaz.
  • count(*): İstenilen değere bağlı kayıt sayısını döndürür. Boş değer içeren kaydı sayar.
  • first(): İlk değeri döndürür.
  • last(): Son değeri döndürür.
  • max(): En büyük değeri döndürür.
  • min(): En küçük değeri döndürür.
  • sum(): Toplam değeri döndürür.


 select count(Meslek) from tblKomsular  


Insert Kullanımının SQL'den Farkı



   Bilinmesi gereken önemli noktalardan birisi; HQL'de doğrudan tabloya ekleme yapamazsınız; ancak bir tablodan diğer tabloya ekleme yapabilirsiniz [1].

Alt Sorguların Kullanımı


   Alt sorgular, sorgusu oldukları ana sorgudan önce çalıştırılırlar. Parantez içine yazılılırlar ve "where" sözcüğüyle birlikte kullanılarak istenilen sorgu yanıtının aralığını daraltmaya yardımcı olurlar [1,4].

 select bolumad from bolumler as bolum where bolumgelir> (bolumgelir avg() from bolum)  

Örnek HQL Sorgusu

 var bloglar = s.CreateQuery("from Blog b where b.Baslik = :baslik and b.Altbaslik = :altbaslik")  
   .SetParameter("baslik","Nil Busra Ozer Kisisel Blog")  
   .SetParameter("altbaslik", "Hibernate Query Language")  
   .List<Blog>();  

 
   Bugünlük anlatacaklarım bu kadar. HQL çok derin bir konu olduğu için özellikle temel kullanımlarına değinmek istedim. Bir sonraki yazımda görüşmek üzere, hoşçakalın..

Kaynaklar


[1]HibernateQueryLanguage,http://www.tutorialspoint.com/hibernate/hibernate_query_language.htm, Nisan 8, 2015.

[2]Introducing HQL: The Object-Oriented Query Language from Hibernate, http://www.developer.com/open/article.php/3322131/Introducing-HQL-The-Object-Oriented-Query-Language-from-Hibernate.htm, Nisan 8, 2015.

[3]Using HQL (Hibernate Query Langıage), http://docs.castleproject.org/Active%20Record.Using%20HQL%20(Hibernate%20Query%20language).ashx, Nisan 9, 2015.

[4]NHibernate Queries-Examples, http://ayende.com/blog/4023/nhibernate-queries-examples, Nisan 9, 2015.



5 Nisan 2015 Pazar

Fluent NHibernate CRUD İşlemleri


Herkese merhabalar.

   Bugün sizlere Fluent NHibernate'in temel konusu olan CRUD işlemlerinden bahsedeceğim. Bu işlemleri gerçekleştirmeyi öğrendiğinizde Fluent NHibernate'i daha iyi kavramaya başlayacağınızı fark edeceksiniz. Gelin hep birlikte aşağıdaki örneğimiz ile bu işlemleri anlayalım.

   Örneğimizde teknoloji isimli bir veritabanımız olacak. Bu veritabanımızda, Marka, Telefon ve Televizyon tablolarını oluşturup bunlar üzerinde okuma, kayıt ekleme, kayıt silme ve kayıt güncelleme işlemlerini gerçekleştireceğiz.

   Önceki yazımda bahsettiğim şekilde gerekli dll dosyalarımızı projemize ekleyelim.



   Solution explorer'ımıza aşağıdaki şekilde uygun klasörlerin altında sınıflarımızı  oluşturalım.

   Örneğimizde; iki teknolojik cihaz ve bunların markaları üzerinden gideceğiz. Telefonun marka ile ve Televizyonun marka ile many-to-one ilişkisi vardır. Şöyle ki; bir telefonun bir markası var iken bir marka birden fazla telefona hatta farklı televizyon gibi telefondan farklı cihazların markası olabilmektedir.


Marka.cs


 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 namespace TelefonFluentHibernate.Entites  
 {  
   class Marka  
   {  
     public virtual int MarkaId { get; set; }  
     public virtual string MarkaAd { get; set; }  
   }  
 }  

Telefon.cs


 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 namespace TelefonFluentHibernate.Entites  
 {  
   class Telefon  
   {  
     public virtual int telefonId{get; set;}  
     public virtual string telefonAd { get; set;}  
     public virtual string telefonRenk { get; set; }  
     public virtual int telefonFiyat { get; set; }  
     public virtual Marka telefonMarka { get; set; }  
   }  
 }  

Televizyon.cs


 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 namespace TelefonFluentHibernate.Entites  
 {  
   class Televizyon  
   {  
     public virtual int televizyonId { get; set; }  
     public virtual string televizyonAd { get; set; }  
     public virtual string televizyonRenk { get; set; }  
     public virtual int televizyonFiyat { get; set; }  
     public virtual Marka televizyonMarka { get; set; }  
   }  
 }  

MarkaMap.cs

 using FluentNHibernate.Mapping;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate.Mapping  
 {  
   class MarkaMap : ClassMap <Marka>  
   {  
     public MarkaMap()  
     {  
       Id(x => x.MarkaId);  
       Map(x => x.MarkaAd);  
       Table("Marka");  
     }  
   }  
 }  

TelefonMap.cs

 using FluentNHibernate.Mapping;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate.Mapping  
 {  
   class TelefonMap : ClassMap <Telefon>  
   {  
     public TelefonMap()  
     {  
       Id(x => x.telefonId);  
       Map(x => x.telefonAd);  
       Map(x => x.telefonFiyat);  
       Map(x => x.telefonRenk);  
       References(x => x.telefonMarka).Column("MarkaId");  
       Table("Telefon");  
     }  
   }  
 }  

TelevizyonMap.cs

 using FluentNHibernate.Mapping;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using System.Threading.Tasks;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate.Mapping  
 {  
   class TelevizyonMap : ClassMap <Televizyon>  
   {  
     public TelevizyonMap()  
     {  
       Id(x => x.televizyonId);  
       Map(x => x.televizyonAd);  
       Map(x => x.televizyonFiyat);  
       Map(x => x.televizyonRenk);  
       References(x => x.televizyonMarka).Column("MarkaId");  
       Table("Televizyon");  
     }  
   }  
 }  

NHibernateHelper.cs

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using FluentNHibernate.Cfg;  
 using FluentNHibernate.Cfg.Db;  
 using NHibernate;  
 using NHibernate.Tool.hbm2ddl;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate  
 {  
   public class NHibernateHelper  
   {  
     private static ISessionFactory _sessionFactory;  
     private static ISessionFactory SessionFactory  
     {  
       get  
       {  
         if (_sessionFactory == null)  
           InitializeSessionFactory();  
         return _sessionFactory;  
       }  
     }  
     private static void InitializeSessionFactory()  
     {  
       _sessionFactory = Fluently.Configure()  
         .Database(MySQLConfiguration.Standard  
                .ConnectionString(  
                  @"Server=localhost; Port=3306;Database=teknoloji; Uid=root; Pwd=;")  
                .ShowSql()  
         )  
         .Mappings(m =>  
              m.FluentMappings  
                .AddFromAssemblyOf<Program>())  
         .ExposeConfiguration(cfg => new SchemaExport(cfg)  
                         .Create(true, true))  
         .BuildSessionFactory();  
     }  
     public static ISession OpenSession()  
     {  
       return SessionFactory.OpenSession();  
     }  
   }  
 }  

Program.cs

 using NHibernate;  
 using NHibernate.Criterion;  
 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using TelefonFluentHibernate.Entites;  
 namespace TelefonFluentHibernate  
 {  
   class Program  
   {  
     static void Main(string[] args)  
     {  
       var telefonNNote4 = new Telefon  
       {  
         telefonAd = "note 4",  
         telefonFiyat = 500,  
         telefonRenk = "beyaz"  
       };  
       var televizyon = new Televizyon  
       {  
         televizyonAd = "tv1",  
         televizyonRenk = "siyah",  
         televizyonFiyat = 1000  
       };  
       var televizyon2 = new Televizyon  
       {  
         televizyonAd = "tv2",  
         televizyonRenk = "beyaz",  
         televizyonFiyat = 1430  
       };  
       var markaSamsung = new Marka  
       {  
         MarkaAd = "samsung"  
       };  
       var markaApple = new Marka  
       {  
         MarkaAd = "apple"  
       };  
       //Create kısmı. Telefon Ekle  
       Ekle<Telefon>(telefonNNote4);  
       //Televizyon ekle  
       Ekle<Televizyon>(televizyon);  
       Ekle<Televizyon>(televizyon2);  
       //Marka ekle  
       Ekle<Marka>(markaSamsung);  
       Ekle<Marka>(markaApple);  
       //Update kısmı. Telefonu güncelle  
       telefonNNote4.telefonMarka = markaSamsung;  
       Guncelle<Telefon>(telefonNNote4);  
       //Televizyonu güncelle  
       televizyon.televizyonMarka = markaApple;  
       televizyon.televizyonRenk = "pembe";  
       Guncelle<Televizyon>(televizyon);  
       televizyon2.televizyonMarka = markaApple;  
       Guncelle<Televizyon>(televizyon2);  
       //Read kısmı   
       Marka marka = Oku("apple");  
       Console.WriteLine("Okunan satir: "+marka.MarkaId+" - "+marka.MarkaAd);  
       //Delete kısmı. Televizyon sil  
       Sil<Televizyon>(televizyon);  
     }  
     private static void Ekle<T>(T yeniKayit)  
     {  
       using (var session = NHibernateHelper.OpenSession())  
       {  
         using (var transaction = session.BeginTransaction())  
         {  
           session.Save(yeniKayit);  
           transaction.Commit();  
           Console.WriteLine("Yeni kayıt eklendi.");  
         }  
       }  
     }  
     private static void Guncelle<T>(T guncelKayit)  
     {  
       using (var session = NHibernateHelper.OpenSession())  
       {  
         using (var transaction = session.BeginTransaction())  
         {  
           session.SaveOrUpdate(guncelKayit);  
           transaction.Commit();  
           Console.WriteLine("Kayit güncellendi. ");  
         }  
       }  
     }  
     private static void Sil<T>(T silKayit)  
     {  
       using (var session = NHibernateHelper.OpenSession())  
       {  
         using (var transaction = session.BeginTransaction())  
         {  
           session.Delete(silKayit);  
           transaction.Commit();  
           Console.WriteLine("Kayit silindi. ");  
         }  
       }  
     }  
     private static Marka Oku(string markaAdi)  
     {  
       using (var session = NHibernateHelper.OpenSession())  
       {  
         Marka markaQuery = (from markaNesnesi in session.QueryOver<Marka>()  
                   where markaNesnesi.MarkaAd == markaAdi  
                   select markaNesnesi).SingleOrDefault();  
         /*IQuery q2 = session.CreateQuery("from Marka WHERE markaAd='" + markaAdi + "';");  
         var markaListesi = q2.List<Marka>();*/  
         Console.WriteLine("Uygun satır bulundu: " + markaQuery.MarkaAd);  
         return markaQuery;  
       }  
     }  
   }  
 }  

Konsol Çıktısı

 alter table telefon drop foreign key FKA4173F7AC8A29C0D  
 alter table Televizyon drop foreign key FK7ADB542AC8A29C0D  
   drop table if exists Marka  
   drop table if exists telefon  
   drop table if exists Televizyon  
   create table Marka (  
     MarkaId INTEGER NOT NULL AUTO_INCREMENT,  
     MarkaAd VARCHAR(255),  
     primary key (MarkaId)  
   )  
   create table telefon (  
     telefonId INTEGER NOT NULL AUTO_INCREMENT,  
     telefonAd VARCHAR(255),  
     telefonFiyat INTEGER,  
     telefonRenk VARCHAR(255),  
     MarkaId INTEGER,  
     primary key (telefonId)  
   )  
   create table Televizyon (  
     televizyonId INTEGER NOT NULL AUTO_INCREMENT,  
     televizyonAd VARCHAR(255),  
     televizyonFiyat INTEGER,  
     televizyonRenk VARCHAR(255),  
     MarkaId INTEGER,  
     primary key (televizyonId)  
   )  
   alter table telefon  
     add index (MarkaId),  
     add constraint FKA4173F7AC8A29C0D  
     foreign key (MarkaId)  
     references Marka (MarkaId)  
   alter table Televizyon  
     add index (MarkaId),  
     add constraint FK7ADB542AC8A29C0D  
     foreign key (MarkaId)  
     references Marka (MarkaId)  
 NHibernate: INSERT INTO telefon (telefonAd, telefonFiyat, telefonRenk, MarkaId)  
 VALUES (?p0, ?p1, ?p2, ?p3);?p0 = 'note 4' [Type: String (6)], ?p1 = 500 [Type:  
 Int32 (0)], ?p2 = 'beyaz' [Type: String (5)], ?p3 = NULL [Type: Int32 (0)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: INSERT INTO Televizyon (televizyonAd, televizyonFiyat, televizyonRen  
 k, MarkaId) VALUES (?p0, ?p1, ?p2, ?p3);?p0 = 'tv1' [Type: String (3)], ?p1 = 10  
 00 [Type: Int32 (0)], ?p2 = 'siyah' [Type: String (5)], ?p3 = NULL [Type: Int32  
 (0)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: INSERT INTO Televizyon (televizyonAd, televizyonFiyat, televizyonRen  
 k, MarkaId) VALUES (?p0, ?p1, ?p2, ?p3);?p0 = 'tv2' [Type: String (3)], ?p1 = 14  
 30 [Type: Int32 (0)], ?p2 = 'beyaz' [Type: String (5)], ?p3 = NULL [Type: Int32  
 (0)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: INSERT INTO Marka (MarkaAd) VALUES (?p0);?p0 = 'samsung' [Type: Stri  
 ng (7)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: INSERT INTO Marka (MarkaAd) VALUES (?p0);?p0 = 'apple' [Type: String  
  (5)]  
 NHibernate: SELECT LAST_INSERT_ID()  
 Yeni kayıt eklendi.  
 NHibernate: UPDATE telefon SET telefonAd = ?p0, telefonFiyat = ?p1, telefonRenk  
 = ?p2, MarkaId = ?p3 WHERE telefonId = ?p4;?p0 = 'note 4' [Type: String (6)], ?p  
 1 = 500 [Type: Int32 (0)], ?p2 = 'beyaz' [Type: String (5)], ?p3 = 1 [Type: Int3  
 2 (0)], ?p4 = 1 [Type: Int32 (0)]  
 Kayit güncellendi.  
 NHibernate: UPDATE Televizyon SET televizyonAd = ?p0, televizyonFiyat = ?p1, tel  
 evizyonRenk = ?p2, MarkaId = ?p3 WHERE televizyonId = ?p4;?p0 = 'tv1' [Type: Str  
 ing (3)], ?p1 = 1000 [Type: Int32 (0)], ?p2 = 'pembe' [Type: String (5)], ?p3 =  
 2 [Type: Int32 (0)], ?p4 = 1 [Type: Int32 (0)]  
 Kayit güncellendi.  
 NHibernate: UPDATE Televizyon SET televizyonAd = ?p0, televizyonFiyat = ?p1, tel  
 evizyonRenk = ?p2, MarkaId = ?p3 WHERE televizyonId = ?p4;?p0 = 'tv2' [Type: Str  
 ing (3)], ?p1 = 1430 [Type: Int32 (0)], ?p2 = 'beyaz' [Type: String (5)], ?p3 =  
 2 [Type: Int32 (0)], ?p4 = 2 [Type: Int32 (0)]  
 Kayit güncellendi.  
 NHibernate: SELECT this_.MarkaId as MarkaId0_0_, this_.MarkaAd as MarkaAd0_0_ FR  
 OM Marka this_ WHERE this_.MarkaAd = ?p0;?p0 = 'apple' [Type: String (5)]  
 Uygun satır bulundu: apple  
 Okunan satir: 2 - apple  
 NHibernate: DELETE FROM Televizyon WHERE televizyonId = ?p0;?p0 = 1 [Type: Int32  
  (0)]  
 Kayit silindi.  

    Yukarıdaki örnekte kodu yorumları ile birlikte çok rahat anlayacaksınız. Sadece üç tane entity ve üç tane mapping sınıfımız var ve bunlar üzerinde; ekleme, okuma, güncelleme ve silme işlemlerini gerçekleştiriyoruz. Dikkat etmeniz gereken özellikle önemli gördüğüm noktalara değinmek istiyorum. Marka ile Telefon veya Marka ile Televizyon arasındaki ilişki many-to-one olduğundan dolayı; referans olarak many olan tarafta yani Telefonda ve Televizyonda Marka'yı belirtmek zorundayız. "References" kullanımını many olan kısımda yazdığımızı üzerine basa basa söylemek istiyorum aksi taktirde durduk yere hatalar ile karşılaşırsınız. İkinci olarak söylemek istediğim; Marka tipindeki Oku metodu ile markayı okuduğumuz zaman karşımıza çıkan ilk kaydı döndürmek istersek, aşağıdaki şekilde SingleOrDefault yapısını kullanmalıyız.

 Marka markaQuery = (from markaNesnesi in session.QueryOver<Marka>()  
                   where markaNesnesi.MarkaAd == markaAdi  
                   select markaNesnesi).SingleOrDefault();  

   Eğer aradığımız marka adına sahip tüm nesneleri döndürmek istiyorsak, aşağıdaki kod parçasının yardımı ile okuma yapmalıyız.

 IQuery q2 = session.CreateQuery("from Marka WHERE markaAd='" + markaAdi + "';");  
         var markaListesi = q2.List<Marka>();  

   Bugünlük anlatacaklarım bu kadar. Herkese bol kodlu günler.

Referanslar

[1] Create, read, update and delete, http://en.wikipedia.org/wiki/Create,_read,_update_and_delete, Nisan 2, 2015.

[2]Simplify Database Operations with Generic Fluent NHibernate, http://www.codeproject.com/Articles/380022/Simplify-Database-Operations-with-Generic-Fluent-N, Nisan 3, 2015.

[3]Tutorial on NHibernate and FluentNhibernate,  https://thehelios.wordpress.com/2011/07/11/tutorial-on-nhibernate-and-fluentnhibernate/, Nisan 4, 2015.