Nhibernate-4

Evet dizimizin son yazısına gelmiş bulunuyoruz.

Önceki Yazılar

Nullable
Nullable tipler Nhibernate kullanımı için çok önemli bir ayrıntıdır.Bir nesne kaydettiğimizi düşünelim.Nesnenin integer tipte alanları olsun.Siz o alana bir değer atamadığınız sürece o alanlar “0” dır. Nhibernate bu durumda bu değerin sizin tarafınızdan mı atandığını yoksa başlangıç değeri mi olduğunu kestiremez ve veritabanına o alanlar için 0 yazar.Nhibernate, nesnenin alanlarının kullanıcı tarafından set edilip edilmediğini o alanların değerinin “null” olup olmadığına bakarak karar verir.Bu durumda nesnelerimizin veritabanında karşılığı “allow null” olan alanları için nullable tipler kullanmalıyız.Nullable ya da int? gibi..Bu durum Datetime gibi tipler için de geçerlidir.Normal Datetime tipi kullanırsanız ve o alana atama yapmazsanız Nhibernate veritabanına 01/01/1900 yazar. O alanın boş geçilememesi gibi bir şartımız varsa bu durumda nullable tipler yerine normal tipleri kullanabiliriz.

Nhibernate ve Exception
Nhibernate exception fırlattığında .net ortamında aldığınız hata genelde generic hatalardır.Bunun yerine hatanın derinlerine inip “inner excepiton” da ne yazdığına mutlaka bakın.Yani “Lazy laoding” hatası alırsınız ama innerexception içinde “Ad” alanı bulunamadı yazabilir.Aslında “Ad” alanı bulunumadığı için lazy loading hatası alırsınız ama bunu ilk etapta farkedemeyebilirsiniz.Bu yüzden innerexception içinde yazan mesajı baz alarak problemlerinizi çözmeye çalışın.

SetMaxResult
Sorgumuza döndürmesini istediğimiz maksimum kayıt sayısını bildirebiliyoruz.

criteria.SetMaxResult(25);

IgnoreCase
Oracle ve örnek uygulamamızda da kullandığımız SQLite gibi case-sensitive veritabanlarında insensitive sorgulama yapabilmemiz için IgnoreCase metodunu kullanırız.

Expression.Eq("Ad", "Hasan").IgnoreCase();

Subcriteria, Sum,Avg
Şimdi count,avg gibi sql fonksiyonların ve alt sorguların nhibernate ile nasıl gerçeklendiğini inceleyelim:

=>Öğrenci numarası Hasan’ın öğrenci numarasını alalım.

ICriteria criteria = session.CreateCriteria(typeof (Ogrenci));
criteria.Add(Expression.Eq("Ad", "Hasan"));
criteria.Add(Expression.Eq("Soyad", "Fehmi"));
criteria.SetProjection(Projections.Property("OgrenciId"));
IList<string> liste= criteria.List<string>();

Bu tür spesifik sonuçlar döndürmeye yönelik sorgularımız bir ya da bir kaç hesaplanmış alan döndüreceği için listemizin dönüş tipi artık üzerinde sorgu yaptığımız nesnenin tipinde değil de “string” tipindedir.Çünkü artık nesnesinin tamamını döndürmüyoruz.

=>Öğrenci numarası Hasan’ın öğrenci numarasından büyük olan öğrencileri bulalım.

ICriteria criteria = session.CreateCriteria(typeof (Ogrenci));
DetachedCriteria dtCriteria1 = DetachedCriteria.For(typeof(Ogrenci));
dtCriteria1.Add(Expression.Eq("Ad", "Hasan"));
dtCriteria1.Add(Expression.Eq("Soyad", "Fehmi"));
dtCriteria1.SetProjection(Projections.Property("OgrenciId"));

DetachedCriteria dtCriteria = DetachedCriteria.For(typeof(Ogrenci));
dtCriteria.SetProjection(Projections.Avg("OgrenciId"));
criteria.Add(Subqueries.PropertyGe("OgrenciId", dtCriteria1));
IList<Ogrenci> liste = criteria.List<Ogrenci>();

Bu sorguda bazı şartları sağlayan öğrencileri döndürdüğümüz için liste tipimiz artık “Ogrenci”.

=>Öğrenci numarası Hasan’ın öğrenci numarasından büyük olan öğrencileri yada adında “is” karakteri geçen öğrencileri Ad sırasına göre getiriyoruz.

 ICriteria criteria = session.CreateCriteria(typeof (Ogrenci));
<div style="display: none"><a href='http://bestwritingservices.org/'>college essay writing services</a></div>DetachedCriteria dtCriteria1 = DetachedCriteria.For(typeof(Ogrenci));
dtCriteria1.Add(Expression.Eq("Ad", "Hasan"));
dtCriteria1.Add(Expression.Eq("Soyad", "Fehmi"));
dtCriteria1.SetProjection(Projections.Property("OgrenciId"));

DetachedCriteria dtCriteria = DetachedCriteria.For(typeof(Ogrenci));
dtCriteria.SetProjection(Projections.Avg("OgrenciId"));
criteria.Add(Expression.Or
( Subqueries.PropertyGe("OgrenciId",dtCriteria),
  Expression.Like("Ad","%İs%"))
);
criteria.AddOrder(Order.Asc("Ad")); 
IList<Ogrenci> liste = criteria.List<Ogrenci>();

=>Şimdi olayı biraz daha karmaşık hale getirelim. Öğrenci numarası Hasan’ın öğrenci numarasından büyük olan öğrencileri yada adında “is” karakteri geçen öğrencileri adlarına göre gruplayıp her grubun elaman sayısını ve OgrenciId ortalamasını getiriyoruz.

ISession session = NHibernateHttpModule.CurrentSession;
ICriteria criteria = session.CreateCriteria(typeof(Ogrenci));
DetachedCriteria dtCriteria1 = DetachedCriteria.For(typeof(Ogrenci));
dtCriteria1.Add(Expression.Eq("Ad", "Hasan").IgnoreCase());
dtCriteria1.Add(Expression.Eq("Soyad", "Fehmi").IgnoreCase());
dtCriteria1.SetProjection(Projections.Property("OgrenciId"));

DetachedCriteria dtCriteria = DetachedCriteria.For(typeof(Ogrenci));
dtCriteria.SetProjection(Projections.Avg("OgrenciId"));
dtCriteria.Add(Expression.Or(
                             Subqueries.PropertyGe("OgrenciId ", dtCriteria),
                             Expression.Like("Ad", "%İs%").IgnoreCase()
                            )
               ); 
criteria.SetProjection(Projections.ProjectionList()
                                    .Add(Projections.GroupProperty("Ad"),"Sayi")
                                    .Add(Projections.Count("Ad"),"Ad")
                                    .Add(Projections.Avg("OgrenciId"),"Ortalama")
                       );
IList<object[]> list = criteria.List<object[]>();

Dönüş tipimiz artık bir dizi listesi.Çünkü her sonucun kendi içinde bir dizisi var.Bu gelen sonucu bir grid’e bağlayacağımızı farzedelim.Bu durumda IList tipindeki listemizi anlamlı bir tipe çevirelim.Örrneğin çok sevdiğimiz DataTable’a çevirelim.

DataTable dt = new DataTable();
ProjectionList pl = (ProjectionList)criteria.GetType().GetProperty("Projection").GetValue(criteria, null);

foreach (string str in pl.Aliases)
{
         DataColumn dc = new DataColumn(str);
         dt.Columns.Add(dc);
}

foreach (object[] objarray in list)
{
         DataRow dr = dt.NewRow();
         int i = 0;
foreach (object obj in objarray)
   	{
      	   dr[i] = obj.ToString();
         i++;
      }
    dt.Rows.Add(dr);
}
return dt;
.Add(Projections.GroupProperty("Ad"),"Sayi")
.Add(Projections.Count("Ad"),"Ad")
.Add(Projections.Avg("OgrenciId"),"Ortalama")

Yukarıda gördüğünüz “Sayi”, “Ad”, “Ortalama” ifadeleri bizim grid’ datafield olarak tanıtacağımız alias serisi..
Grid bağladıktan sonra ortaya aşağıdaki gibi bir sonuç çıkar.

Distinct
Nhibernate içinde distinct şu şekilde kullanılır.

.Add(Projections.Distinct(Projections.Property("OgrenciId")));

OgrenciId alanı üzerinden distinct yapacağımıız bildiriyoruz.

Örnek uygulama
Yazı dizimizin en başında bahsettiğimiz örnek uygulamaya buradan erişebilirsiniz. Veri tabanı olarak SQLite seçtim.Böylece veritabanı bağlantıları ile uğraşmadan uygulamayı indirir indirirmez çalıştırabileceksiniz.Kodlama VS2008 ortamında c# ile yapıldı.

Böylece Nhibernate yazı dizimizi ana başlıklara değinerek bitirmiş olduk.Vaktimiz olursa ActiveRecord ile alakalı bir yazı yazmayı düşünüyorum.

3 thoughts on “Nhibernate-4

Comments are closed.