20 Mart 2015 Cuma

Fluent NHibernate Eşleştirme İlişki Çeşitleri


Herkese merhabalar.

   Bugün sizlere eşleştirme çeşitlerinden bahsetmek istiyorum. One-to-many, many-to-one, many-to-many, one-to-one olmak üzere 4 çeşit eşleştirme tipinden bahsedeceğiz. Bu eşleştirme çeşitlerini öğrenirken, geçen hafta anlatmış olduğum terimlerin kullanımını daha iyi anlayacaksınız.

1. One-to-One İlişkisi


    Bu eşleştirme tipinde Türkçe karşılığı ile bire bir ilişkisi vardır. Çok yaygın kurulan bir ilişki çeşidi değildir. Örnek verecek olursak; bir arabanın bir direksiyonu vardır ve o direksiyon da ancak bir arabaya ait olabilir. One-to-one ilişkisini aşağıdaki örnek ile daha iyi anlayacaksınız. Aşağıdaki örnekte; one-to-one ilişkisini sağlamak için iki sınıf da birbirinin özelliğini içermelidir. Tek çocuklu bir aileyi düşünün. Bir annenin sadece bir tane çocuğu vardır; aynı şekilde çocuğun da bir tane annesi vardır.

 public class Anne  
 {  
  public virtual int Id {get;set;}  
  public virtual string isim {get;set;}  
  public virtual string soyisim {get;set;}  
  public virtual Cocuk cocukisim { get; set; }  
 }  
 public class Cocuk  
 {  
  public virtual int Id {get;set;}  
  public virtual string isim {get;set;}  
  public virtual string soyisim {get;set;}  
  public virtual Anne anneisim;  
 }  


 public AnneMap()  
 {  
  HasOne(x => x.cocukisim)  
    .Cascade.All();  
 }  
 public CocukMap()  
 {  
  References(x => x.anneisim)  
    .Unique();  
 }  

   Yukarıda one-to-one mapping ilişkisinin genel yapısını görmüş olduk. Mapping sınıflarının içindeki HasOne ve References'ın kullanımına dikkat edin. References terimini kullanıyorsanız; bu ilişkinin karşılıklı birebir ilişkisi olduğunu belirtmek için Unique terimini kullanmayı unutmamalısınız [1].

2. Many-to-One İlişkisi


   Bu ilişki tipinden örneği ile birlikte ikinci hafta bahsetmiştik. Lütfen inceleyiniz. Bu ilişki çeşidini hatırlamak adına örnek verecek olursak; bir sınıf düşünün, bu sınıfın birden fazla öğretmeni olabilir; ama bir öğretmen sadece bir sınıfa ders veriyor şeklinde bir ilişki ayarlamak istediğiniz zaman many-to-one ilişkisi kurulmuş olacak. References teriminin many olan kısımda kullanıldığına dikkat ediniz.


3. One-to-Many İlişkisi


   Many-to-one ilişkisinin tersi şeklinde düşünebiliriz. Aşağıdaki örnek ile daha iyi anlayacaksınız [2].

 public class Sinif  
 {  
   public virtual int Id { get; set; }  
   public virtual string Ad { get; set; }  
   public virtual Ogretmen Ogretmen { get; set; }  
 }  
 public class SinifMap : ClassMap<Sinif>  
 {  
   public Sinif Map()  
   {  
     Id(u => u.Id).GeneratedBy.Identity();  
     Map(u => u.Ad).Nullable();  
     References(x => x.Ogretmen)  
       .Column("OgretmenId")  
       .Not.Nullable();   
   }  
 }  


 public class Ogretmen   
  {   
   public virtual int Id { get; set; }   
   public virtual string Ad { get; set; }   
   public virtual IList&lt;Sinif&gt; Siniflar { get; set; }   
   public Ogretmen()   
   {   
    Siniflar = new List&lt;Sinif&gt;();   
   }   
  }   
  public class OgretmenMap : ClassMap<Ogretmen>  
  {   
   public OgretmenMap()   
   {   
    Id(u =&gt; u.Id).GeneratedBy.Identity();   
    Map(u =&gt; u.Ad).Nullable();   
    HasMany(u =&gt; u.Siniflar)   
     .KeyColumn("OgretmenId")   
     .Inverse()   
     .Cascade.All();   
   }   
  }  

   
   Yukarıdaki örnekte bir öğretmen birden fazla sınıfın dersine girmektedir; ancak her sınıfa bir tane öğretmen girmektedir. Bu yüzden References terimi many olan "SinifMap" sınıfının içinde ve HasMany terimi ise one olan tarafta yazılmıştır [3].

4. Many-to-Many İlişkisi


   Yukarıdaki örnekten devam edecek olursak; bu ilişki tipinde,  bir sınıfın dersine birden fazla öğretmen girebiliyorsa, bir öğretmen de birden fazla sınıfın dersine girebilecektir. Aşağıdaki örnekte ise bir elbiseyi birden fazla kişi sipariş edebilir ve sipariş eden kişi birden fazla elbise sipariş edebilir. Böylelikle many-to-many ilişkisi sağlanmış olur [4].

 class Siparis  
 {  
   public virtual IList<Giysi> Giysiler { get; protected set; }  
 }  
 class Giysi  
 {  
   public virtual IList<Siparis> Siparisler { get; protected set; }  
 }  


 public class SiparisMap : ClassMap<Siparis>  
 {  
   public SiparisMap()  
   {  
     HasManyToMany(x => x.Giysiler)  
       .Cascade.All()  
       .Table("SiparisGiysi");  
   }  
 }  
 public class GiysiMap : ClassMap<Giysi>  
 {  
   public GiysiMap()  
   {  
     HasManyToMany(x => x.Siparisler)  
       .Cascade.All()  
       .Inverse()  
       .Table("SiparisGiysi");  
   }  
 }  


   Bugünlük anlatacaklarım bu kadar, bir sonraki yazımda CRUD işlemlerinden bahsedeceğim, hoşçakalın..

Kaynaklar

[1] Fluent NHibernate One-to-One mapping, http://stackoverflow.com/questions/15724562/fluent-nhibernate-one-to-one-mapping, Mart 18, 2015.

[2]NHIBERBATE 2: MAPPING RELATIONSHIPS AND FLUENT MAPPING, https://www.packtpub.com/books/content/nhibernate-2-mapping-relationships-and-fluent-mapping, Mart 18, 2015.

[3] Fluent NHibernate Has Many Mapping, http://frankdecaire.blogspot.com.tr/2014/04/fluent-nhibernate-hasmany-mapping.html, Mart 19, 2015.

[4]Many to Many Mapping in Fluent NHibernate,  http://www.duncanmcdougall.co.uk/articles/manytomany-fluentnhibernate.html, Mart 19, 2015.

15 Mart 2015 Pazar

Fluent NHibernate ile İlişkisel Nesneler Tasarlamak, Lazy Loading ve Eager Loading


Herkese merhabalar.

Bugün sizlere ilişkisel nesneler tasarlarken bilmeniz gereken bazı kavramlardan ve Fluent NHibernate'de bilmeniz gereken önemli noktalardan ikisi olan Lazy Loading ve Eager Loading'ten bahsetmek istiyorum. 

Id

   Id metodu kullanılarak Id eşleştirilmesi yapılır [1].

 Id(x => x.Id);  

Map edilecek olan Id'nin ismi Id olarak istenmiyorsa Column metodu kullanılarak aşağıdaki şekilde değiştirilebilir [1].

 Id(x => x.Id)  
  .Column("ogrenciId")  
  .GeneratedBy.Assigned();  

Map

Map metodu ile veritabanı ve class'ların eşleşitirlmesi yapılır [1].

 Map(x => x.FirstName);  

References

   Many to one ilişkilendirilmesinde kullanılır. Many tarafında yazılır. Bunun bir örneğini geçen haftaki yazımda incelemiştik. Many olan tarafta yazılır. HasMany/one-to-many, References ilişkilendirilmesinin bir başka türüdür one tarafında yazılırlar [1].

HasManyToMany/many-to-many

Many to many ilişkilendirilmesinde kullanılır [2].

 HasManyToMany(x => x.Kitaplar);  

HasOne/one-to-one

   One to one ilişkilendirilmesinde kullanılır. Bu ilişkilendirilmede HasOne metodunu kullanıyorken foreign key'inizi belirtmek isterseniz; PropertyRef() metodunu kullanabilirsiniz. Eğer References metodunu kullanıyorsanız; çift taraflı eşleştirmenin one-to-one olduğunu göstermek için .Unique() belirtecini kullanmalısınız [1].

 public class ArabaMap : ArabaMap<Araba>  
 {  
   public ArabaMap()  
   {  
     Table( "Araclar.dbo.Araba" );  
     Id( x => x.ArabaId );  
     Map( x => x.Ad );  
     Map( x => x.yil );  
     HasOne( x => x.Direksiyon ).PropertyRef( x => x.Araba);  
   }  
 }  
 public class DireksiyonMap : ClassMap<Direksiyonl>  
 {  
   public DireksiyonMap()  
   {  
     Table( "Araclar.dbo.Direksiyon" );  
     Id( x => x.DireksiyonId );  
     Map( x => x.Cap );  
     Map( x => x.Renk );  
     References( x => x.Araba, "ArabaId" ).Unique();  
   }  
 }  

Yukarıdaki örnekte araba ile direksiyon eşleştirilmesi one-to-one olmuştur ve bu ilişki eşleştirme sınıflarında yukarıdaki şekilde belirtilmelidir. Her arabanın bir tane direksiyonu olur ve o direksiyon ancak bir tane arabaya ait olabilir.

Lazy Loading

   Lazy Loading veya Eager Loading'in etkin olması durumu programın performansını önemli derecede etkilemektedir. Lazy loading, nesneyi oluşturduğuz zaman o nesneye bağlı olan diğer nesneler de çağırdığınızda onunla birlikte gelmemesi durumudur [3]. Çağırılan nesne ile ilgili diğer nesenelerinde beraberinde glmesini istiyorsanız, Lazy Loading etkinken bu durumu belirtmeniz gerekmektedir. Çağrılan ilgili veri persistent, ona bağlı olan veri ise transient olarak geçmektedir. Lazy Loading, olabildiğince minimum veri ile çalışmayı sağlayarak programın performansını arttırmak için kullanılır. Fluent NHibernate'de default olarak Lazy Loading etkindir [4].

   Lazy Loading'in default olarak gelmesini istemiyorsanız aşağıdaki kod parçası ile bu özelliği devre dışı bırakabilirsiniz [3].

 Not.LazyLoad();  

Geçen hafta bahsettiğimiz convention sınıflarında aşağıdaki kod parçası ile Lazy Loading'i devre dışı bırakabilirsiniz.

 var conventions = new Conventions();  
 conventions.DefaultLazyLoad = false;  
 
Eşleştirme sınıfınızın içinde aşağıdaki şekilde Lazy Loading'i devre dışı bırakabilirsiniz.

  using System;
using System.Collections.Generic;
using System.Linq; using System.Text;
using IlkFluentNHibernateProjem.Entites;
using FluentNHibernate.Mapping;
public class OgrenciMap : ClassMap<Ogrenci>
namespace IlkFluentNHibernateProjem.Mapping { { //Constructor
public OgrenciMap() { Id(x => x.Id); Map(x => x.Ad);
References(x => x.OgrenciBolum).Column("BolumId").Not.LazyLoad();
Map(x => x.Soyad); Map(x => x.Donem); Table("Ogrenci"); } }
}

Eager Loading

   Eager loading, nesneyi oluşturduğuz zaman o nesneye bağlı olan diğer nesnelerin de çağırmadığınız halde otomatik olarak onunla birlikte gelmesi durumudur [5]. Gereksiz verilerin de ilgili veri ile gelmesi, programın performansını Lazy Loading kullanımına kıyasla yadsınamayacak kadar düşürecektir [5].

   Bugünlük anlatacaklarım bu kadar, bir sonraki yazımda eşleştirme çeşitlerine yönelik örnekler yapacağız, şimdilik hoşçakalın..

Kaynaklar

[1]  Fluent Mapping, https://github.com/jagregory/fluent-nhibernate/wiki/Fluent-mapping, Mart 11, 2015.

[2] Fluent-nhibernate-create-many-to-many-relationship-table, https://d4dilip.wordpress.com/2011/01/15/fluent-nhibernate-create-many-to-many-relationship-table/, Mart 11, 2015.

[3] Difference between Lazy Loading and Eager Loading, http://www.dotnet-tricks.com/Tutorial/entityframework/RIWW210913-Difference-between-Lazy-Loading-and-Eager-Loading.html, Mart 12, 2015.

[4] Lazy Loading in Fluent NHibernate, http://tempvalue.blogspot.com.tr/2012/05/lazyloading-in-fluent-nhibernate.html, Mart 12, 2015.

[5] Not.LazyLoad - Eager Loading with NHibernate 3.0, http://www.philliphaydon.com/2011/01/not-lazyload-eager-loading-with-nhibernate-3-0/ Mart 13, 2015.

8 Mart 2015 Pazar

Fluent NHibernate Kullanımı ve Convention Sınıfları


Herkese merhabalar.

     Bugün sizlere Fluent NHibernate'in projeye eklenmesi ve nasıl kullanıldığına dair bir örnek göstererek Fluent NHibernate kodlamasına giriş yapacağız. Ayrıca, Fluent NHibernate'te kullanılan Conventionlar üzerinde konuşacağız. Eminim ki bu yazımla Fluent NHibernate'i daha iyi tanımaya başlayacaksınız.

 1. NHibernate Conventionlar'ı

     NHibernate'in desteklediği Convention'lar aşağıda belirttiğim 2 durum için kullanılmaktadır [1].

  • Tablo ve kolon isimleri, eşleştirmede özel olarak belirtilmediği zamanlar
  • Full domain eşleştrimesi

1.1. Tablo ve Kolon İsimlerinin Adlandırılması

       NHibernate'te  tablo ve kolon isimlerini özel olarak belirtmediğiniz durumlarda NHibernate'in isimlendirme stratejisi devreye girerek "sınıf" ve "property"isimleri tablo ve kolon isimlerine verilir, benzer şekilde tersi de gerçekleşmektedir. NHibernate'in iki tane isimlerindirme stratejisi vardır [1].

Default Naming stratejisi: Configuration kısmında isimlendirme stratejisi ile ilgili ekstra bir şey belirtmediğiniz sürece bu strateji devreye girerek isimlendirmeleri birebir gerçekleştirir. Örneğin; kodunuzdaki sınıfınızın ismi "Öğrenci" ise veritabanınızda oluşan tablonun adı da doğrudan doğruya "Öğrenci"olacaktır; çünkü siz configuration kısmında bir şey belirtmediniz ve bu yüzden otomatik olarak "Default Naming" devreye girmiş oldu [1].


Improved Naming stratejisi: Eşleştirme yapılırken sınıf isminizi tablo isminize eşleştiriken alt tire  kullanılır. Örneğin; "BenimEvim" adlı sınıfınız,  "benim_evim" adlı bir tabloya eşleştirilir. Bu isimlendirme stratejisini kullanabilmek için configuration'da aşağıdaki şekilde değişiklik yapmalısınız [1].


 1: cfg.SetNamingStrategy(ImprovedNamingStrategy.Instance); 

Full Domain Eşleştrimesi: Eşleştirmeyi kod ile yapmanın avantajlarından birisi de Conventionlar sayesinde eşleştirmelerinizin otomatik olarak yapılabilmesidir. Bu nasıl olacak ki dediğinizi duyar gibiyim. Şöyle oluyor; sizin sınıflarınızın veritabanı nesneleri ile nasıl ilişkilendirilip eşleştirilmenin yapılacağına karar veren sınıflar var [2]. Şimdilik size bu sınıfları tanıtacağım; ancak ileriki yazılarımda sadece bunları nasıl kullanacağınızı bilmekten öte bu sınıfları kendinize göre uyarlayabilecek hale geleceksiniz ve kendi Convention sınıflarınızı yazabilir hale geleceksiniz. Aşağıda bu Convention sınıf örneklerinin bazılarını tanıtacağım. Daha detaylı bilgi için bu siteyi takip edebilirsiniz.

ColumnNullabilityConvention: Bu sınıf, eğer kolonun boş bırakılabilirliği belirtilmediyse otomatik olarak boş bırakılamama durumunu seçmektedir [2].

 public class ColumnNullabilityConvention  
   : IPropertyConvention, IPropertyConventionAcceptance  
 {  
   public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)  
   {  
     criteria.Expect(x => x.Nullable, Is.Not.Set);  
   }  
   public void Apply(IPropertyInstance instance)  
   {  
     instance.Not.Nullable();  
   }  
 }  

PrimaryKeyNameConvention: Bu sınıf, primary key olan her kolonun entity adının sonuna Id son ekini alarak isimlendirilmesini sağlar [2].


 public class PrimaryKeyNameConvention : IIdConvention  
 {  
   public void Apply(IIdentityInstance instance)  
   {  
     instance.Column(instance.EntityType.Name + "Id");  
   }  
 }  

StringColumnLengthConvention: String tipindeki kolonun uzunluk sınırı belirtilmediyse bu sınıf sayesinde otomatik olarak uzunluk 100 olarak atanır [2].

 public class StringColumnLengthConvention  
   : IPropertyConvention, IPropertyConventionAcceptance  
 {  
   public void Accept(IAcceptanceCriteria<IPropertyInspector> criteria)  
   {  
     criteria.Expect(x => x.Type == typeof(string))  
       .Expect(x => x.Length == 0);  
   }  
   public void Apply(IPropertyInstance instance)  
   {  
     instance.Length(100);  
   }  
 }  

 2. Fluent NHibernate Projeye Eklenmesi ve İlk Örneğimiz


     Örneğe geçmeden önce Fluent NHibernate ile ilgili dll dosyalarını referans olarak göstermemiz gerekiyor. Bu siteden gidişatı takip ettiğinizde eklenmesinin çok kolay olduğunu göreceksiniz [3].

     Aşağıda gördüğünüz gibi projeye başlamadan önce gerekli dll dosyalarını References kısmına ekledik. Unutmadan şunu da belirtmeliyim ki ben MySql veritabanı kullandığım için MySql.Data.dll dosyasını referans kısmına eklemek zorunda kaldım. Eğer MySql veritabanı kullanıyorsanız bu detayı gözden kaçırmamalısınız.




   Aşağıdaki örnekte, okul isimli veritabanında öğrenci ve bölümü olmak üzere eşleştirme ilişkisi "many to one" olan iki tablo oluşturdum. Şöyle ki bir öğrenci sadece bir bölüme kayıtlı olabiliyorken bir bölüm birden fazla öğrenciye ait olabiliyor. Eşleştirme ilişkilerini önümüzdeki haftalarda çeşitleri ile birlikte detaylı bir şekilde anlatacağım. Bu örnek için many to one'ın ne anlama geldiğini bilmeniz yeterli olacaktır. Solution Explorer'ımızın görünümü aşağıdaki gibidir [4].


Bolum.cs:

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 namespace IlkFluentNHibernateProjem.Entites  
 {  
   public class Bolum  
   {  
     public virtual int Id { get; set; }  
     public virtual string BolumAd { get; set; }  
     public virtual string BolumKodu { get; set; }  
   }  
 }  

Ogrenci.cs:

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 namespace IlkFluentNHibernateProjem.Entites  
 {  
   public class Ogrenci  
   {  
     public virtual int Id {get; set;}  
     public virtual string Ad { get; set; }  
     public virtual string Soyad { get; set; }  
     public virtual string Donem { get; set; }  
     public virtual Bolum OgrenciBolum { get; set; }  
   }  
 }  

    Bu sınıfta Bolum tipinde "OgrenciBolum" oluşturulmasının sebebi; "OgrenciMap" sayfasında "OgrenciBolum" kısmına Bolum tablosundaki BolumId'yi referans olarak gösterebilme amacı ile yazılmıştır. Böylelikle bir öğrenci eklediğiniz zaman OgrenciBolum kısmına BolumId'yi ekleyecektir.

BolumMap.cs:

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using FluentNHibernate.Mapping;  
 using IlkFluentNHibernateProjem.Entites;  
 namespace IlkFluentNHibernateProjem.Mapping  
 {  
   public class BolumMap : ClassMap<Bolum>  
   {  
     //Constructor  
     public BolumMap()  
     {  
       Id(x => x.Id);  
       Map(x => x.BolumAd);  
       Map(x => x.BolumKodu);  
       Table("Bolum");  
     }  
   }  
 }  

OgrenciMap.cs:

 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using FluentNHibernate.Mapping;  
 using IlkFluentNHibernateProjem.Entites;  
 namespace IlkFluentNHibernateProjem.Mapping  
 {  
   public class OgrenciMap : ClassMap<Ogrenci>  
   {  
     //Constructor  
     public OgrenciMap()  
     {  
       Id(x => x.Id);  
       Map(x => x.Ad);  
       Map(x => x.Soyad);  
       Map(x => x.Donem);  
       References(x => x.OgrenciBolum).Column("BolumId");  
       Table("Ogrenci");  
     }  
   }  
 }  

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 IlkFluentNHibernateProjem.Entites;  
 namespace IlkFluentNHibernateProjem  
 {  
   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=okul; 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();  
     }  
   }  
 }  

   Gerekli konfigürasyonları gerçekleştiren sınıftır. Veritabanı çeşidini değiştirdiğinizde tek yapmanız gereken bu dosyadaki ConnectionString kısmında değişiklik yapmak. İşte Fluent NHibernate'in güzelliklerinden birisi, farklı veritabanları ile çalışmak Fluent NHibernate ile bu kadar basit.

Program.cs:


 using System;  
 using System.Collections.Generic;  
 using System.Linq;  
 using System.Text;  
 using IlkFluentNHibernateProjem.Entites;  
 namespace IlkFluentNHibernateProjem  
 {  
   class Program  
   {  
     static void Main(string[] args)  
     {  
       Bolum bolum;  
       using (var session = NHibernateHelper.OpenSession())   
        {   
          using (var transaction = session.BeginTransaction())  
          {  
            bolum = new Bolum {BolumAd = "Bilgisayar Mühendisliği", BolumKodu = "BIM" };  
            session.Save(bolum);  
            transaction.Commit();  
            Console.WriteLine("Bolum eklendi: " + bolum.BolumAd);  
            session.Close();  
          }   
        }  
       using (var session = NHibernateHelper.OpenSession())  
       {  
         using (var transaction = session.BeginTransaction())  
         {  
           var ogrenci = new Ogrenci { Ad = "Nil Buşra", Soyad = "Özer", Donem = "8", OgrenciBolum = bolum };  
           session.Save(ogrenci);  
           transaction.Commit();  
           Console.WriteLine("Ogrenci kaydedildi: " + ogrenci.Ad + " " + ogrenci.Soyad);  
           session.Close();  
         }  
       }  
     }  
   }  
 }  

   Şunu söylemeliyim ki her işlem için sessionları açıp kapamanız gerekmektedir. Aksi taktirde hatalar ile karşılaşacaksınız.
Arka Planda Çalışan Sorgular:



Program Çalıştıktan Sonra Veritabanı:


    Bu haftalık anlatacaklarım bu kadar, umarım faydalı bir yazı olmuştur. Bir sonraki yazımda; Fluent NHibernate ile ilişkisel nesneler tasarlamak, Lazy Loading ve Eager Loading konularından bahsedeceğim. Şimdilik görüşmek üzere, hoşçakalın..


Kaynaklar

[1] NHibernate Conventions, http://weblogs.asp.net/ricardoperes/nhibernate-conventions, Mart 1, 2015.

[2] Fluent NHibernate conventions-examples, http://marcinobel.com/index.php/fluent-nhibernate-conventions-examples/, Mart 2, 2015.

[3] nuget, https://www.nuget.org/packages/FluentNHibernate/1.3.0.717, Mart 2, 2015.

[4] Start Fluent NHibernate, http://www.codeproject.com/Articles/305493/Start-Fluent-NHibernate, Mart 2, 2015.

28 Şubat 2015 Cumartesi

ORM, NHibernate ve Fluent NHibernate Giriş

Herkese merhabalar.

   Uzun bir aradan sonra yeniden birlikteyiz. Bugünlerde merak sardığım NHibernate ve Fluent NHibernate konularını gelin hep birlikte örnekleri ile beraber anlayalım. Bu hafta konuyu daha iyi anlamanız açısından direkt kodlara girmek istemeyerek tanım odaklı anlatacağım; ancak önümüzdeki haftalarda bol bol örnekler ile konuları detaylı bir şekilde inceleyeceğiz. NHibernate’e geçmeden önce neyi neden yapacağımızı daha iyi anlamanız açısından, ORM kavramından bahsetmek istiyorum.

1. ORM 


      ORM (Object-Relational Mapping), nesneye yönelik bir programlama metodu sunan, ilişkisel
veritabanları ile nesne tabanlı uygulamaların arasındaki veri uyumunu sağlayan, nesnelerimizi ilişkisel veritabanındaki tablomuza bağlayan ve veri alış-verişini bizim için yapan bir tekniktir[1]. Neden biz bu tekniği kullanalım dediğinizi duyar gibiyim. Nedenlerini sıralayacak olursak; yazılan kodun veritabanından bağımsızlığını sunuyor. Bu sayede, veritabanınızı değiştirmek zorunda kaldığınızda, kodlamanızda sadece bağlantı ayarlarında değişiklik yapmanız gerekecek, böylelikle büyük bir külfetten kurtulmuş olacaksınız. ORM araçlarının çoğu açık kaynak kodludur, programlama dilinden bağımsızdır[2]. Ayrıca ORM, polymorphism, caching, transaction gibi karşılaşılan birçok soruna çözüm sunarak yazılımcıların işini kolaylaştırıyor[2].

2. NHibernate


    NHibernate’in ne olduğunu anlamak için öncelikle Hibernate’in tanımını bilmeliyiz. Hibernate, Java platformunda yazılmış, yukarıda bahsetmiş olduğum ORM’in araçlarından biridir[3]. NHibernate ise Hibernate’in .NET çatısı için yeniden yazılmış bir türevidir[3]. NHibernate, SQL sorgu cümleleri yazarak projelerimizdeki veritabanıyla iletişime geçme zahmetinden bizi kurtarır, ilgili veriler üzerinde ekleme, silme, güncelleme, veri çekme ve  birçok işlemi kolaylıkla yapmamıza olanak sağlar[4]. Veri yapılarınızı bildirirken iki farklı yol izleyebilirsiniz. Birincisi xml kodları ile veri yapınızı bildirmek diğeri ise ilgili sınıfları yazıp NHibernate’e sınıfa göre tabloları vb. oluşturmasını istediğinizi bildirmek ki ben bu yöntemi tercih edeceğim, bu yöntem Fluent NHibernate kullanımına girmektedir; ama yinede örneklerinizde tercih sizindir[4]. Hangi yöntem kolayınıza geliyorsa o yöntemi tercih etmelisiniz. Her ne kadar adı ürkünç gelse de konunun içine girdiğiniz zaman, özellikle büyük veritabanları olan kurumsal şirketlerden birinde yazılımcıysanız sizi ne büyük zahmetlerden kurtardığını gördükçe NHibernate vazgeçilmeziniz olacak. NHibernate ile ilgili bazı terimleri uygulama geliştirmeden önce bilmeniz, neyi ne için kullandığınızı daha rahat anlamanızı sağlayacaktır.

Session: Veritabanına bağlantı, veri çekimi ve basit bir “Unit of Work” implementasyonudur.

ICreteria API: Tekrar kullanılabilir, hızlı sorgular üretmek için geliştirililmiş bir yöntemdir.

HQL: String bazlı nesneler üzerine de uygulanabilen bir sorgu dilidir.

Schema Mapping: Veritabanında hangi tabloların hangi nesnelerle; hangi kolonların, hangi property’ler ile eşleşeceğini, ilişkilerin neler olduğunu belirttiğimiz hbm.xml uzantılı dosyalardır.

Dialect: NHibernate’in hangi veritabanı dilini kullanması gerektiğini belirttiğimiz veritabanına özel dildir[5]. 

NHibernate Avantajları:

Daha yüksek üretkenlik.
   o Sizin adınıza veritabanı  işlerini organize ederek sizi karmaşalardan kurtararak veriminizin artmasını sağlar[6].

Daha kolay bakım.
   o Daha az satır kod[6].

Veritabanı çeşidinden bağımsızlık.
   o ORM aracılığıyla yazılan veritabanı erişim kodları sayesinde kolaylıkla farklı veritabanlarında çalıştırılabilir[6].

NHibernate  Dezavantajları:

Performans[6].
Çoğu zaman Stored Procedure ve View’lardan yavaş çalışır[6].
XML mapping karışıklığı[6].
Öğrenilmesi biraz zaman alabilir[6].

3. Fluent NHibernate


     Fluent NHibernate’in NHibernate’in özelliklerinden farklı olan tarafı, veri yapılarının XML dosyası ile değil de kodlardaki sınıf yapıları ile eşleştirilmesidir[7]. Bu yöntem bazı kullanıcılara daha kolay gelmektedir; ancak her iki yöntemin de kendine has avantaj ve dezavantajları mevcuttur.

Fluent NHibernate Avantajları:

Daha az kod tekrarı.
    o Defalarca XML kodlarını tekrarlamanıza gerek kalmaz[8].

XML’e kıyasla daha anlaşılır kodlar[8].

XML kodları compiler tarafından derlenmediği için programı çalıştırmadığınız sürece hatalarınızı göremezsiniz[9].

Test edilebilirlik[8].

Veritabanı çeşidinden bağımsızlık[8].

Automapping özelliği mevcuttur[9].

XML’e kıyasla daha az kod satırı ile eşlemenizi daha kolay şekilde gerçekleştirebilirsiniz[9].

Fluent NHibernate  Dezavantajları:

Performans kaybı daha çoktur[6].

NHibernate’e göre daha yeni gelişen bir teknoloji olduğundan ortaya çıkabilecek hata payı NHibernate’e kıyasla daha fazladır[6].

Çok fazla sınıf yapısı içermesi gereken programlarda duruma göre XML mapping kullanmak daha uygun olabilmektedir[6].

ORM, NHibernate ve Fluent NHibernate kavramlarını gördükten sonra bundan sonra hangi konuları anlatmayı planladığıma bakalım.

1. Fluent NHibernate kullanımı ve Convention sınıfları.

2. Fluent NHibernate ile ilişkisel nesneler tasarlamak, Lazy Loading, Eager Loading.

3. Fluent NHibernate eşleme çeşitleri(mappings).

4. Fluent NHibernate CRUD işlemleri.

5. HQL(Hibernate Query Language).

6. Fluent NHibernate ile kullanıcı tanımlı tipler kullanmak.

7. Fluent NHibernate Automapping.

8. Convention sınıflarının yeniden yazılması.

9. Kalıtımsal eşleme.

Bu haftalık anlatacaklarım bu kadar, bir sonraki yazımda sizlere Fluent NHibernate kullanımı ve Convention sınıflarından bahsedeceğim. Şimdilik görüşmek üzere, hoşçakalın..


Kaynaklar


[1] ORM Nedir, http://www.cagataybulut.com/2013/07/orm-nedir.html, Şubat 21, 2015.

[2] ORM nedir ve ne zaman kullanma(ma)lıyız,  http://www.barisdere.com/2010/12/orm-nedir-ve-ne-zaman-kullanmamaliyiz-2/, Şubat 21, 2015.

[3] Hibernate, NHibernate Nedir, http://tanertemelce.blogspot.com.tr/2013/01/hibernate-nhibernate-nedir.html, Şubat 23, 2015.

[4] Yeni yazı disizi: NHibernate, http://b.zor.lu/yeni-yazi-disizi-nhibernate/, Şubat 23, 2015.

[5] NHibernate’e Başlama Klavuzu, http://www.tahircakmak.com/2008/05/nhibernatee-baslama-klavuzu_20.html, Şubat 22, 2015.

[6] NHibernate mappings using xml, attributes, and Fluent NHibernate, http://www.davesquared.net/2008/09/nhibernate-mappings-using-xml.html, Şubat 24, 2015.

[7]FluentNHibernate NhibernateGiriş-1,http://bilgehanyildiz.com/2011/11/10/fluentnhibernatenhibernategiris1/, Şubat 24, 2015.

[8] Fluent NHibernate introduction and quick start guide
, http://marekblotny.blogspot.com.tr/2008/12/fluent-nhibernate-introduction-and.html, Şubat 22, 2015.

[9] NHibernate for Entity Framework Developers: Part 1 – Fluent NHibernate, http://weblogs.asp.net/manavi/nhibernate-for-entity-framework-developers-part-1-fluent-nhibernate, Şubat 26, 2015.

4 Ocak 2014 Cumartesi

Typeface.js Kütüphanesi
     
         Herkese Merhabalar.

     Bir hafta aradan sonra sizlerle tekrardan beraberiz. Bu hafta sizlere typeface.js isimli JavaScript kütüphanesinden bahsetmek istiyorum. Kullanımı oldukça basit olan ve kompleks bir yapıda olmayan bu kütüphanenin yardımımıza koşması ile web sitenizde yazılarınıza istediğiniz fontu eklemek için artık flash kullanmanıza, resimler oluşturmanıza gerek kalmadı. Bu kütüphane sayesinde sitenize dilediğiniz fontu ve rengi kolay bir şekilde ekleyebilirsiniz. Cümlenin harfleri arasındaki boşluk, harflerin üst ve alttaki boşlukları da tercihinize uygun bir şekilde ayarlanabilmektedir. Kütüphaneyi bu siteden indirip projenize ekleyebilirsiniz. Web sitenize font eklemek için typeface.js kütüphanesini kullanacağınız zaman, bu kütüphanenin okuyabileceği fontları indirip eklemeniz gerekir. Bu 3 fontu bu siteden indirip projenize ekleyebilirsiniz. Bu fontların neler olduğuna hep beraber bir göz atalım.

Font Ailesi: Helvetiker

 1. Regular (Sıradan)                                     



2. Bold (Kalın)



3. Italic (Eğik)


4. Bold_Italic (Kalın ve Eğik)


Font Ailesi: Optimer ve Gentilis 


   Bu diğer iki fontun tiplerine de bu siteden bakabilirsiniz.

   Bu fontların sayfamıza nasıl ekleneceğini aşağıdaki kod parçacığında gösterdim.

 <script src="/js/typeface/typeface-0.14.js" type="text/javascript"/>  
 <script src="/js/typeface/fonts/helvetiker_bold.typeface.js" type="text/javascript"/>  
 <script src="/js/typeface/fonts/optimer_bold.typeface.js" type="text/javascript"/>  

   Aşağıda sizler için ASP.NET ortamında yapmış olduğum örneğe bir göz atalım. Öncelikle Solution Explorer'a gereken dosyalarımızı  aşağıdaki gibi  ekliyoruz.


   Aşağıdaki kodlarda typeface.js kütüphanesinin fontlarını kullanarak değişik font ailelerinden farklı renklerde örnekler gösterdim. Umarım anlaşılır ve faydalı bir örnek olmuştur. Örneğin, projede bulunan aşağıdaki kod parçasında, typeface.js kütüphanesinin içerdiği Elephant isimli font ailesi örneğini kullanarak yazımın bu fontta ve yeşil renkte olmasını sağladım.

  <div class="typeface-js" style="font-family:Elephant;color:green">   
         <center>Font family: Elephant!</center>   
       </div>  

Proje Kodları:


 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>  
 <!DOCTYPE html>  
 <html xmlns="http://www.w3.org/1999/xhtml">  
 <head runat="server">  
   <title>Typeface JavaScript Kütüphanesi Örnek</title>  
 <meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />  
      <link rel="stylesheet" type="text/css" href="style.css" />  
      <script type="text/javascript" src="js/typeface-0.10.js"></script>  
      <script type="text/javascript" src="js/optimer_regular.typeface.js"></script>  
      <script type="text/javascript" src="js/qlassik_medium_regular.typeface.js"></script>  
 </head>  
 <body>  
      <div id="page-wrap">  
           <div class="headline typeface-js">  
                Nil'in Typeface Denemesi :)  
           </div>  
           <p style="color:yellow">  
                TYPEFACE JAVASCRIPT KÜTÜHANESİ ÖRNEĞİ  
           </p>  
           <table style="border:dotted; border-color:aqua;height:220px;width:320px"><tr><td>  
           <div class="typeface-js" style="font-family: 'Angsana New';color:hotpink">  
                <center>Font family: Angsana New!</center>  
           </div>  
     <div class="typeface-js" style="font-family: 'Agency FB';">  
                <center>Font family: Agency FB!</center>  
           </div>  
      <div class="typeface-js" style="font-family: 'Aharoni';color:red">  
                <center>Font family: Aharoni!</center>  
           </div>  
      <div class="typeface-js" style="font-family: 'Cordia New';color:chocolate">  
                <center>Font family: Cordia New!</center>  
           </div>  
      <div class="typeface-js" style="font-family: 'Aparajita';color:aqua";>  
                <center>Font family: Aparajita!</center>  
           </div>  
       <div class="typeface-js" style="font-family:'Castellar';color:pink">  
                <center>Font family: Castellar!</center>  
           </div>  
       <div class="typeface-js" style="font-family: 'Bookman Old Style';color:orange">  
                <center>Font family: Bookman Old Style!</center>  
           </div>  
       <div class="typeface-js" style="font-family:Elephant;color:green">  
                <center>Font family: Elephant!</center>  
           </div></td></tr>  
           </table>  
      </div>  
 </body>  
 </html>  

29 Aralık 2013 Pazar

Knockout.js Kütüphanesi
     
        Herkese Merhabalar.

     Bir hafta aradan sonra sizlerle tekrardan beraberiz. Bu hafta sizlere knockout.js isimli JavaScript kütüphanesinden bahsetmek istiyorum. Bind mekanizması sayesinde otomatik güncelleme yapmamızı sağlayan bu kütüphane, özellikle büyük ve kompleks olan projelerde JavaScript ve HTML kodlarının iç içe geçmesi ile programcının yaşadığı zorluklardan dolayı meydana gelen zaman kaybını önlemekte bize oldukça yardımcı olan bir kütüphanedir. Modelleme mantığıyla tasarım iç içe kullanılmış olduğu için programcının her ikisine de iyi derecede hakim olması zor olabilir. Böyle karışıklıkların yaşanacağı durumlarda knockout.js yardımımıza koşacak. Nasıl olacak dediğinizi duyar gibiyim. Şöyle ki; knockout.js kütüphanesi zengin ve etkileşimli kullanıcı arayüzleri oluşturma imkanı sağlar. Dinamik olarak değişen arayüz elemanları var ise kullanım ve geliştirme kolaylığı ile öne çıkmaktadır. MVVM (Model View ViewModel) dizayn modelini kullanarak geliştirme yapılır. Modeldeki değerler, kullanıcı hareketlerine göre güncellenir. Bu kütüphanenin en etkileyici özelliği veri bağlama yapısıdır. Kütüphaneyi kullanmadan önce, bu siteden indirebilirsiniz.
Bu kütüphane 3 temel özellik üzerine kurulmuştur;

  • Şablon kullanımı
  • Veri bağlama
  • Observable(gözlenebilirlik) ve bağımlılık izlemesi

MVVM(Model View ViewModel):

Bu kütüphanede MVVM dizayn modelini kullanarak geliştirme yapacaksak bu modelin ne olduğunu anlamamız gerekir, haydi neymiş bu  MVVM bir bakalım...  Model, View ve ViewModel adında 3 yapıdan oluşmaktadır. Amaçları arasında arayüz yapan kişinin arka tarafta nasıl bir iş geliştirildiğini bilmeden işini yapabiliyor olması, daha çabuk genişlemeye müsait bir yapının ortaya çıkarılması sayılabilir. Model, verileri temsil etmektedir. View kullanıcıya sunulan görüntü, ViewModel ise asıl işin geliştirildiği yapıdır. View'ın Model'i bilmesine gerek yoktur. ViewModel aracılık yapmaktadır.


Aşağıda sizler için ASP.NET ortamında yapmış olduğum örneği bir inceleyelim. Öncelikle kütüphanemizi Solution Explorer'a ekliyoruz.

 

Aşağıdaki kod parçacığında  "viewModel1" isimli View Modelimizi oluşturduk. Modeldeki fonksiyon ve diğer ögelerin observable(gözlenebilir) olarak oluşturulmasının nedeni dinamik olarak değiştirilebilme özelliğinin eklenebilmesidir. Ayrıca, modelde belirlemiş olduğumuz fonksiyon, listeye hayvan isimlerini eklememizi sağlayan fonksiyondur.


 var viewModel1 = {  
   kedi: ko.observable(),  
   array: ko.observableArray(),  
   hayvanEkle: function () {  
     this.array.push(this.kedi());  
   }  
 };  



Aşağıdaki kod parçacığı Knockout'u aktifleştirmemizi sağlar. Peki Knockout modeldeki fonksiyonu nasıl algılıyor? O da elbette Knockout'un applyBindings metoduna viewModel1'i göndermemiz ile gerçekleşiyor.



  ko.applyBindings(viewModel1);  

Aşağıdaki kod parçacığı, kullanıcı arayüzünde görülen View'umuzdur. Textbox'a girilen değerlerin listeye eklendiği kısımdır.

  <ul data-bind="foreach:array">  
           <li data-bind="text: $data"></li>  
         </ul>  

Aşağıdaki kod parçacığında, textbox içerisine yazılan değerlerin ViewModel içerisinde tanımlanmış kedi ögesinin yerini alması ile güncellenme sağlanır.

 <h1 data-bind="text:kedi">Kedi</h1>  
         <input type="text" data-bind="value:kedi,valueUpdate:'afterkeydown'" />  


Proje Kodları:


 <%@ Page Language="C#" AutoEventWireup="true" CodeFile="Default.aspx.cs" Inherits="_Default" %>  
 <!DOCTYPE html>  
 <html xmlns="http://www.w3.org/1999/xhtml">  
 <head runat="server">  
   <title>KNOCKOUTJS ÖRNEK</title>  
 </head>  
 <body>  
   <h1 style="background-color:azure">KNOCKOUT JAVASCRIPT KÜTÜPHANESİ ÖRNEĞİ :)</h1>  
   <table>  
     <tr>  
       <td style="border: dashed">  
         <h1 data-bind="text:kedi">Kedi</h1>  
         <input type="text" data-bind="value:kedi,valueUpdate:'afterkeydown'" />  
         <input type="submit" data-bind="click: hayvanEkle" />  
         <ul data-bind="foreach:array">  
           <li data-bind="text: $data"></li>  
         </ul>  
       </td>  
     </tr>  
   </table>  
   <script src="knockout-3.0.0.js"></script>  
   <script>var viewModel1 = {  
   kedi: ko.observable(),  
   array: ko.observableArray(),  
   hayvanEkle: function () {  
     this.array.push(this.kedi());  
   }  
 };  
     viewModel1.array.push("kedi");  
     viewModel1.array.push("köpek");  
     viewModel1.array.push("tavşan");  
     ko.applyBindings(viewModel1);  
   </script>  
 </body>  
 </html>  



Yazıyı Yazarken Dinamik Olarak Alt Başlık Kısmında Görünürkenki Ekran Görüntüsü:



Gönder Butonuna Bastıktan Sonraki Ekran Görüntüsü:



    
Umarım anlaşılır ve yararlı bir örnek olmuştur. Bu haftalık anlatacaklarım bu kadar, bir sonraki     hafta typeface.js kütüphanesinden bahsedeceğim. Şimdilik görüşmek üzere, hoşçakalın...

KAYNAKLAR

1. http://knockoutjs.com/documentation/observables.html

2. http://www.youtube.com/watch?v=JGwRIbWWqjE&desktop_uri=%2Fwatch%3Fv%3DJGwRIbWWqjE&app=desktop

3. http://www.ercanaydogan.com/post/2012/02/16/Knockoutjs-JavaScript-MVVM-I.aspx

4. http://www.nodejstr.com/2012/08/knockout-js-ve-nodejs-ile-kullanm.html