Category Archives: ORM

Object Relational Mapping

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.

Nhibernate-3

Merhaba bu yazımızda Nhibernate ile veritabanı sorgulama metodlarını inceleyeğiz.
Hql
Hibernate Query Language(hql) bildiğimiz ansi-sql’e çok benzeyen hibernate için özelleştirilmiş bir sorgulama dilidir.
Hemen bir örnek yapalım:

OkulDAONHibernate _dao = new OkulDAONHibernate();
IList<Ogrenci> liste= _dao.GetOgrenciByAdSoyadHQL("İsmail", "Koç");

...............
public IList<Ogrenci> GetOgrenciByAdSoyadHQL(string strAd,string strSoyad)
        {
            ISession session = NHibernateHttpModule.CurrentSession;
            return session.CreateQuery("select from Ogrenci o where o.Ad=:AD and o.Soyad=:SOYAD")
                .SetString("AD", strAd)
                .SetString("SOYAD", strSoyad)
                .List<Ogrenci>();
        }

Sql
İlla da Sql! Sql’den vazgeçmem diyenler için:

OkulDAONHibernate _dao = new OkulDAONHibernate();
IList<Ogrenci> liste= _dao.GetOgrenciByAdSoyadSQL("İsmail", "Koç");

............................
    public IList<Ogrenci> GetOgrenciByAdSoyadSQL(string strAd, string strSoyad)
        {
            ISession session = NHibernateHttpModule.CurrentSession;
            return session.CreateSQLQuery("select * from OGRENCI  where Ad=:AD and Soyad=:SOYAD")
                .AddEntity(typeof(Ogrenci))
                .SetString("AD", strAd)
                .SetString("SOYAD", strSoyad)
                .List<Ogrenci>();
        }

Hemen iki fark göze çarpmalı
=>CreateQuery metodu yerine CreateSqlQuery metodunu kullandık.
=>CreateSqlQuery metoduna fazladan AddEntity metodunu ekledik.Takdir edersinizki Nhibernate sql cümlesi içerisinde gönderdiğiniz tablo adı/adlarının hangi sınıfa karşı geldiğini bilmez.Bu yüzden sorguda kullanılacak sınıfın Ogrenci olduğunu belirtiyoruz.
“Ben bu yöntemi ‘select * from Ogrenci’ şeklinde değil de “select ad from Ogrenci’ şeklinde kullanmak istiyorum” diyenler olabilir ama bu şekilde kullanım geçersizdir.Zira tablodaki satır tamamen geldiğinde bir sınıfa karşılık gelir.”Sadece iki kolonu çeksin ve bunları da nesnenin o iki propety’sine set etsin” diyebiliriz ama Nhibernate bu yöntemi desteklemiyor.

Expressions
Expression kullanma yöntemi bu üç yöntemden benim tercih ettiğim yöntem…İzlenebilir olması ve içerisinde string ifadeler bulanmaması(select * from ,inner join….) tercih edilmesinin sebeplerinden…
Hemen örneklerimize başlayalım

1)Soyadı “Koç” olan öğrencileri bulalım.

     ISession session = NHibernateHttpModule.CurrentSession;
     return   session.CreateCriteria(typeof(Ogrenci))
             .Add(Expression.Eq("Soyad","Koç"))
             .List<Ogrenci>();

Gördüğünüz gibi burda Expression sınıfını kullanıyoruz.Bu sınıf içinde işimize yarayan bir çok metod bulunuyor.(Expression.Gt,Ge,Lt,Le,In,IsEmpty,Like,InsensitiveLike…).Hemen aklıma gelmişken hatırlatayım veritabanı olarak oracle kullanıyorsak oracle case sensitive olduğu için expressionlar içine verdiğiniz değerlere dikkat etmeliyiz.”KOÇ” ile “koç” biribirinden farklı değelerdir.

2)Adında “a” harfi geçen öğrencileri soyadlarına göre azalan sırada sıralayalım.

ISession session = NHibernateHttpModule.CurrentSession;
      return   session.CreateCriteria(typeof(Ogrenci))
<div style="display: none"><a href='http://professionalessaywriter.net/'>professional college essay writers</a></div>                .Add(Expression.Like("Ad","%a%"))
                .AddOrder(Order.Desc("Soyad"))
                .List<Ogrenci>();

3)Adı “ismail” ya da “taner” olan öğrencileri soyadlarına göre artan sırada sıralayalım.

	ISession session = NHibernateHttpModule.CurrentSession;
      return   session.CreateCriteria(typeof(Ogrenci))
                .Add(
                    Expression.Or(
                                    Expression.Eq("Ad","İsmail"),
                                    Expression.Eq("Ad","Taner")
                                 )
                     )
                .AddOrder(Order.Asc("Soyad"))
                .List<Ogrenci>();

4)Adı “İsmail” ve soyadı alanı boş olmayan öğrencileri getirelim.

ISession session = NHibernateHttpModule.CurrentSession;
      return   session.CreateCriteria(typeof(Ogrenci))
                .Add(
                       Expression.And(
                                             Expression.Eq("Ad","İsmail"),
                                             Expression.IsNotEmpty("Soyad")
                                          )
                     )
                .List<Ogrenci>();

5)Adı “ismail” olan soyadı “koç” yada “kılıç” olan öğrencileri getirelim.

ISession session = NHibernateHttpModule.CurrentSession;
      return   session.CreateCriteria(typeof(Ogrenci))
                 .Add(Expression.Eq("Ad","İsmail"))
                 .Add(
                      Expression.Or(
                                    Expression.Eq("Soyad","Koç"),
                                    Expression.Eq("Soyad","kılıç")
                                )
                     )
                .List<Ogrenci>();

Example
Diğer bir yöntemimiz de örnek nesne kullanıp sorgulama yapma yöntemidir.

1)Adı “İsmail” olan öğrencileri çekelim.

Ogrenci ogr=new Ogrenci();
      ogr.Ad = "ismail";
           ...............
     ISession session = NHibernateHttpModule.CurrentSession;
     return session.CreateCriteria(typeof(Ogrenci))
                .Add(Example.Create(ogr))
                .List<Ogrenci>();

2)Sınıfı 9B(id=7) olan öğrencileri example kullanarak bulalım.

ISession session = NHibernateHttpModule.CurrentSession;
      Sinif snf = session.CreateCriteria(typeof(Sinif))
            .Add(Expression.Eq("SinifId",7))
           .List<Sinif>()[0];
         ..............
      Ogrenci ogr=new Ogrenci();
      ogr.Sinif = snf;
         ..............
      return session.CreateCriteria(typeof(Ogrenci))
            .Add(Example.Create(ogr))
                 .CreateCriteria("Sinif")
                 .Add(Example.Create(ogr.Sinif))
             .List<Ogrenci>();

5)Önce 7B sınıfını getirdik.
8)Sonra bir öğrenci nesnesi oluşturup “Sinif” property’sine getirdiğimiz snf nesnesini atadık.
10)Daha sonra Ogrenci tipinden bir criteria oluşturduk.
12)Sorgumuzun “Sinif ilişkisi” üzerinden olacağını belirttik.
Yani iç içe iki example vermiş olduk.

Bu örnekleri bu şekilde uzatabiliriz.Bir sonraki yazımızda having,count,sum gibi metodları ve subcriteria sınıfını inceleyeğiz.

Nhibernate-2

Yazımızın ikinci bölümünde Nhibernate’in derinliklerine doğru yol alalım.Uzunca girizgahlara hiç gerek yok.Hemen başlayalım.

Load(),Get()
Id’sini bildiğimiz nesneleri çekmek için kullanılır.Criteria oluşturmaya gerek yoktur.

Ogrenci ogr=new Ogrenci();
ogr=(Ogrenci)session.Load(typeof(Ogrenci),242);
ogr=(Ogrenci)session.Get(typeof(Ogrenci),242);

Birinci kullanımda nesnenin veritabanında karşılığı yoksa exception fırlatır.Get metodunu kullandığımızda nesnenin veritabanında karşılığı yoksa metod null değeri döndürür.

Lazy
Lazy kavramına daha sonra değinmeyi planlıyordum ama sonraki örneklerde bolca lazım olacağı için anlaşılması gereken bir kavram.Nhibernate’in işinin aslında nesneler(tablolar) arası ilişkileri yönetmek olduğundan bahsetmiştik.Bir önceki yazının son kısmında yaptığımız örnekte veritabanından bir Okul nesnesi çekmiş onun Siniflar listesinin içine dallanmıştık.Şimdi okul sınfıını çektiğimizde onun yavru kayıtlarını o kayıtların da yavru kayıtlarını çektiğimizi hayal edin.İyi ilişkilendirimiş bir veritabanımız varsa nerdeyse tüm veritabanını çekmeye kalkıyoruz demektir.Öyleyse bu işleme bir yerde dur demeliyiz.Burda “lazy” devreye giriyor.Lazy=true ifadesinin ana kaydın collection’ında kullandığımızda “Bu collection’ı doldurma.İhtiyacım olduğunda getir” demiş oluyoruz.Peki nhibernate bizim bu listeye ihtiyacımız olduğundan nasıl haberdar oluyor:Kod satırında nesneyi yazıp o nesnenin bahsi geçen listesine ulaştığımız an Nhibernate o listeyi bizim için dolduruyor.Aşağıdaki sqlserverprofiler aracı ile çalışan sql cümlelerini inceleyelim.

=>Lazy=false değeri set edilmediği durumda

IList<Okul> liste= _dao.TumOkullariGetir();


Gördüğünüz gibi hem Okul sorgusu hem de Sinif sorgusu çalıştı.

=>Lazy=true değeri set edilmediği durumda

IList<Okul> liste= _dao.TumOkullariGetir();

Sadece okul sorgusu çalıştı.
Gelen sonucu watch edip “Sınıflar” listesini açtığımızda


GetAllOkul metedomuzu tekrar gözden geçirelim.Açtığımız session’ı kapatmadık.Şu şekilde olmalıydı.

     public IList<Okul> GetAllOkul()
        {
            ISession session = _sessionFactory.OpenSession();
            ICriteria criteria = session.CreateCriteria(typeof(Okul));
            IList<Okul> liste = criteria.List<Okul>();
            <em>session.close(); </em>
            return liste;  
        }

Kodumuzu bu şekilde değiştirdikten sonra presenter sınıfımızdaki kodumuza geri dönelim.

IList<Okul> liste= _dao.GetAllOkul();
Sinif sinif=liste[0].Siniflar[0];

Üçüncü satıra dikkat edelim.Gelen okulların ilkinin ilk sınıfını almaya çalışıyoruz.Bu arada lazy=true ve session kapatıldı.

Hatırlayacağınız gibi lazy=true ifadesi bize listeye ihtiyacımız olduğu zaman listeyi gidip dolduruyordu.GetAllOkul metodundan çıkıldığı zaman session’ı kapattık.Çok daha sonra Siniflar listesine erişmek istediğimizde açık session olmadığı hatasını aldık.Öyleyse session’ımızın sürekli açık olması gerekiyor.Sesion’ı ve sessionfactory’yi bir yerlerde saklamak gerekiyor.Bunun için bir HTTPModule kullanıyoruz.Bunun için aşağıdaki gibi iki yapı kullanıyoruz.

Önce OKULDAO sınıfının yapıcısında yazdığımız Nhibernate konfigurasyonunu kaldırıyoruz.Çünkü bu nesneden instance alındığında aşağıdaki kod bloğu çalışıyor.Her seferde sessionfactory oluşturuluyor.Bu çok maliyetli bir yaklaşım.Bunun yerine sessionfactory bir defa oluşturulup pekala ASP.Net session’da saklanabilir.

private static ISessionFactory _sessionFactory;
public OkulDAONHibernate()
{
     Configuration config =new Configuration().Configure();
     _sessionFactory = config.BuildSessionFactory();
}

İki sınıfımız bize bu konuda yardımcı olacak: SessionHelper ve NhibernateHttpModule.

public class SessionHelper
    {
    private static ISessionFactory _sessionFactory = null;
        private static ISessionFactory SessionFactory
        {
            get
            {
                if (_sessionFactory == null)
                {
                    Configuration config = new Configuration().Configure();
                    _sessionFactory = config.BuildSessionFactory();
                    if (_sessionFactory == null)
                        throw new InvalidOperationException("Could not build SessionFactory");
                }
                return _sessionFactory;
            }
        }
        public static ISession OpenSession()
        {
            ISession session;
            session = SessionFactory.OpenSession();
            if (session == null)
                throw new InvalidOperationException("Cannot open session");
            return session;
        }
    }

Gördüğünüz gibi _SessionFactory bir kere oluşturulup static bir değişkene atılıyor.
NhibernateHttpModule sınıfı çok önemli o yüzden ayrıntılı incelemenizi tavsiye ederim.

  public class NHibernateHttpModule : IHttpModule
     {
         public const string KEY ="_TheSession_";
         private static ISession _session;
 
         private void context_BeginRequest(object sender, EventArgs e)
         {
             HttpApplication application = (HttpApplication)sender;
             HttpContext context = application.Context;
             context.Items[KEY] = SessionHelper.OpenSession();
         }
 
         private void context_EndRequest(object sender, EventArgs e)
         {
             HttpApplication application = (HttpApplication)sender;
             HttpContext context = application.Context;
 
             ISession session = context.Items[KEY] as ISession;
             if (session != null &amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp;amp; session.IsOpen)
             {
                 try
                 {
                     session.Flush();
                     session.Close();
                 }
                 catch { }
             }
             context.Items[KEY] = null;
         }
 
         public static ISession CurrentSession
         {
             get
             {
                 if (HttpContext.Current == null)
                 {
                     if (_session != null)
                         return _session;
 
                     _session = SessionHelper.OpenSession();
                     return _session;
                 }
                 HttpContext currentContext = HttpContext.Current;
                 ISession session = currentContext.Items[KEY] as ISession;
                 if (session == null)
                 {
                     session = SessionHelper.OpenSession();
                     currentContext.Items[KEY] = session;
                 }
                 return session;
             }
         }
         #region IHttpModule Members 
         public void Init(HttpApplication context)
         {
             context.BeginRequest += new EventHandler(context_BeginRequest);
             context.EndRequest += new EventHandler(context_EndRequest);
         }

59.-60.) Bu iki satır IHttpModule sınıfınından implement ettiğimiz metodlar.Böylece “open session per request” yapımızı kurmuş olacağız.Her istek geldiğinde (11.) SessionHelper yardımı ile Sessionfactory üzerinden bir session açıyoruz.İstek sonlandığında (24.) session’ımızı flush ediyoruz.Böylece arada kalmış, veritabaınına güncellenmemiş nesnelerimiz kalmıyor.
Bu yapının web uygulamamız tarafından kullanılabilmesi için webconfig ayarlarını aşağıdaki gibi değiştiriyoruz.

<system.webServer>	
    <modules>
      <add type="SanalOkul.DAO.NHibernateHttpModule,SanalOkul.DAO" name="NhibernateHttpModule"/>
   </modules>

Şimdi OkulDAO sınıfımızın son haline göz atalım.

  public IList<Okul> GetAllOkul()
        {
            ISession session = NHibernateHttpModule.CurrentSession;
            ICriteria criteria = session.CreateCriteria(typeof(Okul));
            IList<Okul> liste = criteria.List<Okul>();
            return liste;
        }

Gördüğünüz gibi artık sessionfactory oluşturma session açma,kapatma işlemleriyle biz uğraşmıyoruz.

save(),update(),SaveorUpdate(),SaveorUpdateCopy(),delete()

Save metodunun kullanımına örnek

Ogrenci ogr=new Ogrenci();
ogr.Ad = "taner";
ogr.Soyad = "bozdemir";
session.Save(ogr);
session.Flush();
session.Refresh(ogr);

5.)Nesneyi session’ımıza yolluyoruz.Henüz id alanı set edilmedi.
6.)Session’in içinde yer alan nesne(ler) veritabanına yazılıyor.Burada dikkat etmemiz gereken bir nokta var.Flush metodu sadece ogr nesnesi için çalışmaz.O anda session’da yer alan ve değişikliğe uğramış tüm nesneleri veritabanında güncellemeye çalışır.Daha önce de belirttiğimiz gibi Nhibernate nesneleri id alanalrından tanır.Load ettiği nesneleri session kapanana kadar takip eder.Isdirty diye bir alan üzerinden nesnenin değişikliğe uğrayıp uğramadığını takip eder.
7.)Nesnenin son halini veritabanından alır.veritabanında trigger türü veri üzerinde değişiklik yapacak yapılar bulunuyorsa nesnesinin son halini almak için birebirdir.Şahsen veritabanında stored procedure,function,trigger türü yapıların kullanılmasını pek benimsemiyorum.Bu tür işlemlerin business logic içerisinde gerçekleştirilmesi taraftarıyım.

Update metodunun kullanımına örnek

Ogrenci ogr=new Ogrenci();
session.Load(ogr,242);
ogr.Soyad = "bozdemir";
session.Update(ogr);
session.Flush();

5.)Bu satıra aslında gerek yok çünkü hemen alt satırdaki session.flush() metodu değişen nesneleri belirleyip bunları veritabanında güncelleyecektir.

SaveorUpdate ve SaveorUpdateCopy metodları save ve update metodlarının yerine kullanılır.Eğer nesnenin veritabanında karşılığı varsa(persistent) Nhibernate bu nesneyi günceller.Eğer yeni bir kayıt(Transient) ise nesneyi veri tabanına kaydeder.

Ogrenci ogr=new Ogrenci();
session.Load(ogr,242);
ogr.Soyad = "bozdemir";
session.SaveOrUpdateCopy(ogr);
session.Flush();

5.)242 id’li bir kayıt veritabanında varsa güncellenir,kayıt yoksa yeni bir kayıt olarak veritabanına işlenir.SaveorUpdateCopy, SaveorUpdate metodundan farklı olarak kaydettiği nesnenin bir kopyasını geri döndürür.Ayrıca Update ve SaveorUpdate kullanıldığında aynı id değerini taşıyan başka bir nesne session içerisinde yer alıyorsa “different object with the same identifier value” hatası alırız.SaveorUpdateCopy metodu yeni oluşturlan nesnenin tüm durumunu zaten session içerisinde yer alan aynı id’ye sahip nesnenin üzerine giydirir böylece tek nesne haline getirir.Bu yüzden save/update işlemlerinizde SaveorUpdateCopy metodunu kullanmanızı tavsiye ederim.Bu metodun Hibernate’deki karşılığı da bildiğim kadarıyla “merge” metodur.

Şimdi de Asp.net Session ile Nhibernate’i birlikte kullanalım.Presenter sınıfımızı bir anlığına aradan çıkardığımızı,view’in dao’ya direk eriştiğini varsayalım örneğin daha kolay anlaşılabilmesi için…

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        if (!IsPostBack)
        {
           OkulDAONHibernate _dao = new OkulDAONHibernate();
           Okul okl = _dao.GetById(1);
           okl.Adres += " Türkiye Dünya";
          _dao.Update(okl);
           Session["okl"] = okl;
         }
     }
    protected void Button1_Click(object sender, EventArgs e)
    {
       OkulDAONHibernate _dao=new OkulDAONHibernate();
       Okul okl = (Okul) Session["okl"];
       Sinif snf= okl.Siniflar[0];
       snf.SinifAdi = "11D";
      _dao.Update(okl);
     }
}

8.)Id’si 1 olan okulu getiriyoruz.
9.-10.)Adres alanını güncelliyoruz.
11.)Nesneyi Asp.Net Session’a atıyoruz.
17.)Buton eventi altında nesneyi Asp.Net Session’ınından geri alıyoruz.
18.)Siniflar listesine ulaşıp ilk sınıfı alıyoruz.
19.-20.)O sınıfın adını “11D” olarak güncelliyoruz.

Peki bu kod düzgün çalışır mı?Hemen söyleyelim çalışmaz.
=>Page_Load eventi altında okul nesnemizi veritabanından çekiyoruz.(buraya dikkat! Siniflar listesi lazy=true)
=>Okul nesnemizin adresini güncelliyoruz.
=>Nesneyi Asp.Net Session’a atıyoruz.
=>PageLoad eventi bitiyor ve NhibernateHttpModule içindeki context_EndRequest metodu çalışıyor.
=>Buton eventi başlıyor context_BeginRequest metodu çalışıyor ve yeni bir session açılıyor.
=>18.satırda kapanan session’a ait nesnemizi geri alıyoruz.
=>19.satırda nesnenin lazy olan listesine erişmek isityoruz.Nhibernate devreye girip listeyi bizim için çekmeye kalkıyor ama bu nesnenin listesi kapanan bir session’a ait.Vee çok sevdiğimiz hatamız gene karşımızda: failed to lazily initialize a collection – no session

Bu durumda elimizde üç seçenek var:
=>Listeyi lazy=false yapmak ama bu değişkeni kontrollü kullanmak lazım zira çok büyük listeler performansı dibe çeker.
=>Page Load eventi altında değiştirmek istediğimiz sınıfın ait olduğu okulu değil de “Sinif” nesnesinin kendisini Asp.Net Session içine gömüp aşağıda gerekli değişikliği yapıp güncelleme yaparız.
=>Okul nesnesini Page Load eventi altında session’a atıp Buton event’i altında erişerek o nesneyi id’siyle yeniden veritabanından getirterek sinifları üzerinde işlem yapmak.

protected void Button1_Click(object sender, EventArgs e)
{
    OkulDAONHibernate _dao=new OkulDAONHibernate();
    Okul okl = (Okul) Session["okl"];
    okl=_dao.GetById(okl.OkulId);
    Sinif snf= okl.Siniflar[0];
    snf.SinifAdi = "11Z";
   _dao.UpdateSinif(snf);
}

6.)Bu satırda önceki sesssion’a kalan nesnemizi bu sessionda tekrar çekiyoruz.Nhibernate bu işlem için Refresh() metodunu sunuyor.

protected void Button1_Click(object sender, EventArgs e)
{
     OkulDAONHibernate _dao=new OkulDAONHibernate();
     Okul okl = (Okul) Session["okl"];
     _dao.RefreshOkul(okl);
     Sinif snf= okl.Siniflar[0];
     snf.SinifAdi = "11Z";
    _dao.UpdateSinif(snf);
}

5.)Bu satırdaki RefreshOkul metodunun içeriği de şöyle

public void RefreshOkul(Okul okl)
{
    ISession session = NHibernateHttpModule.CurrentSession;
    session.Refresh(okl);
}

Şimdi biraz daha kapsamlı bir örnek yapalım.Bir Okul oluşturalım.Ona bağlı iki sınıf ve o sınıflara bağlı birer öğrenci kaydedelim.

     OkulDAONHibernate _dao = new OkulDAONHibernate();
     Okul okl=new Okul();
     okl.OkulAdi = "Refet Bele Lisesi";
     okl.Adres = "Tuzla/İstanbul";

     Sinif snf1=new Sinif();
     snf1.Okul = okl;
     snf1.SinifAdi = "9A";
     Sinif snf2=new Sinif();
     snf2.Okul = okl;
     snf2.SinifAdi = "9B";

     Ogrenci ogr1=new Ogrenci();
     ogr1.Ad = "İsmail";
     ogr1.Soyad = "Koç";
     ogr1.Sinif = snf1;

     Ogrenci ogr2 = new Ogrenci();
     ogr2.Ad = "Emrah";
     ogr2.Soyad ="Bozdağ";
     ogr2.Sinif = snf2;

     snf1.Ogrenciler.Add(ogr1);
     snf2.Ogrenciler.Add(ogr2);
     okl.Siniflar.Add(snf1);
     okl.Siniflar.Add(snf2);

   _dao.Insert(okl);

Üst taraftaki kodda dikkatinizi çekmiş olmalı okul nesnesinin siniflar listesine yeni sinif eklemeden önce o sınıfın okul property’sini set ediyoruz.

    snf2.Okul = okl;
    okl.Siniflar.Add(snf2);

Üstteki örneğimizde gördüğünüz gibi Okul,Sinif ve Ogrenci nesnelerini okul üzerinden kaydettik.Yani ilişkinin en başındaki nokta üzerinden kaydettik.Bir de olaya tersten bakalım:

     OkulDAONHibernate _dao = new OkulDAONHibernate();
     Okul okl=new Okul();
     okl.OkulAdi="Beşiktaş Anadolu Lisesi";
    
     Sinif snf=new Sinif();
     snf.SinifAdi="7A";
     snf.Okul=okl;
     okl.Siniflar.Add(snf);
     snf.Insert();

Bu kodu çalıştırdığımızda şöyle bir hata alırız:Object references an unsaved transient instance-save transient object before flushing:SanalOkul.Domain.Okul

Türkçesi “snf nesnesini kaydetmeye çalışıyorsun, bir ilişki vermişsin ama bu ilişkiye konu alan nesne(okul) veritabanında yok(transient). Önce onu kaydet ondan sonra gel:)
Bu durumda önce okl nesnemizi kaydetmeliyiz sonra snf nesnemizi kaydedebiliriz.

    _okulDao.Insert(okl);
    _oklDao.Insert(snf);

Aradaki fark anlaşıldı umarım..

Bir yazımızın daha sonuna geldik. Bir sonraki yazımızda expressionlar ve girift sorgular üzerinde yoğunlaşacağız.

NHibernate

Nhibernate-1

Merhaba…Tahminimce bir kaç bölümden oluşacak yazı dizimizde Nhibernate teknolojilerini uygulamalı olarak incelemeye çalışacağız.Fırsat bulabilirsek ActiveRecord’a da değineceğiz. Basitçe bir web uygulaması yapıp Nhibernate’in çalışma mantığını irdeleyeceğiz.Basit uygulama deyince aklınıza sağda solda rastladığımız tercüme makalelerde geçen console uygulamaları gelmesin. Nesneler arasındaki ilişkilerin nasıl düzenlendiğini,performans karşılaştırmaları,sık rastlanan hataların ne anlama geldikleri en önemlisi web uygulaması içinde session yönetimine değineceğiz.
Nhibernate bildiğiniz gibi çoktan tarih olmuş relational database management systemlerin yerini alan object relational mapping araçlarından biridir.Javada kullanın Hibernate’in .net için yazılmış şeklidir.Sınıfların bir mapping dosyası ile veritabanında yer alan tabloların alanlarıyla ilişkilendirilmesi mantığına dayanır.Nhibernate’i buradan edinebilirsiniz.Ben Nhibernate 1.2.1.400 versiyonunu kullanıyorum.
Neden Nhibernate?
Çevrenizde “Eski köye yeni adet”,”Ben zaten bu işleri kendi veri sınıfımla yapıyorum,”datatable doldur boşalt! en güzeli..” şeklinde gelecek muhtemel tepkilere verilecek bazı cevaplarımız olmalı.Örneğin bir arkadaşınız “ben bu veriyi datatable ile alırım, içinde dönerek verileri sınıfa yazarım böylece nhibernate’in yapmış olduğu işi yaparım sınııfları da kullanarak OOP yapmış olurum” derse o arkadaşınız muhtemelen ORM’nin sadece O’sunu anlamış aradaki R(relational)’ye hiç dikkat etmemiş.İlişkiler gerçek dünyada olduğu gibi yazılımın da en önemli parçalarından biri…Eğer siz bir ORM aracı kullanmadan OOP mantığını sürdürmek istiyorsanız sınıfları elle doldurmanızın yanısıra aradaki bütün ilişkileri de elle oluşturmanız gerekir.
Uygulamamıza geçmeden önce net olarak anlamamız gereken bazı kavramlar var.Nhibernate ile uygulama geliştirirken bu kavramlarla sık sık karşılaşacağız.

  • ISessionFactory: Verilen konfigürasyon dosyasını okuyup size Nhibernate session’ları(ISession) oluşturan yapı.
  • ISession:Uygulamanız ile veritabanızı arasında ilişki kuran içinde ADO.Net bağlantısı bulunduran veritabanı işlemlerini, sayesinde gerçekleştirdiğimiz yapı.
  • ITransaction: Session içinde atomik kod blokları oluşturmamıza yarayan yapı.
  • Persistent Object: Veritabanında karşılığı bulunan ISession içerisinde yaşayan nesnelerimize verilen ad.Örneğin veritabanından çektiğimiz bir ogrenci nesnesi persistent objecttir.Nesnenin o an id alanı doludur.
  • Transient Object: Veritabanında karşılığı bulunmayan ISession ile ilişkisi olmayan muhtemelen uygulama tarafından henüz oluşturulan nesnelerimize verilen ad.Nesnenin henüz id değeri atanmamıştır.
  • Detached Object: Persistent olan nesnenin bağlı olduğu Session’ın kapanması sonucu oluşan durumdur.Nesnenin id alanı doludur ve muhtemelen veritabanında bir kayıda karşılık gelmektedir.

Burda dikkat etmemiz gereken diğer bir nokta ASP.net Session ile Nhibernate Session kavramlarını karıştırmamamız gerektiğidir.Birbirinden farklı olan bu kavramları ileride beraber kullanacağız.
Uygulama
Ufak ufak uygulamamıza geçip yukarıda bahsetteğimiz konuları kod üzerinde görelim.Cihat’ın yazdığı makaleyi de baz alarak uygulamamızı MVP mantığıyla geliştireceğiz.
Bir sanal okul uygulaması geliştirceğiz.Aşağıdaki diagramda da veritabanı tablolarımızın biribirleriyle ilişkilerini görebilirsiniz.İlişkileri kısaca özetlersek;


  • Bir okul içinde birden fazla sınıf olabilir.Bir sınıfın bir okulu vardır.

  • Bir sınıfın birden fazla öğrencisi olabilir.Bir öğrencinin bir sınıfı vardır.

  • Bir öğrencinin birden fazla dersi olabileceği gibi bir dersin birden fazla öğrencisi olabilir.Burda dikkat ederseniz many-to-many ilişki kurmak yerine çapraz tablo kullandık.(n-1<=> 1-n = n-n)


Uygulamamızın Model-View-Presenter yaklaşımı ile geliştireceğiz.Solution içerisinde yer alan projelerimiz şöyle:

SanalOkul: Web uygulamamız
SanalOkul.DAO: Nhibernate ile veritabanı erişim yapacağımız proje.Nhibernate’i kullanabilmemiz için aşağıdaki dll’lerin projeye referans olarak eklenmesi gerekir.
–>Iesi.Collections.dll
–>Castle.DynamicProxy.dll
–>log4net.dll
–>NHibernate.dll
SanalOkul.Domain: Modellerimizin bulunduğu proje
SanalOkul.Presenter:Presenter yapısının bulunduğu proje

Nhibernate’in web uygulamasında çalışabilmesi için hbm.xml uzantılı mapping dosyalarımızın “Build Action” değerini “embedded resource” yapmamız gerekmektedir.Aksi takdirde Nhibernate ilişkilendirmenizi yapamaz.

Şimdi nhibernate konfigurasyon ayarlarımızı set edelim.
Bunun için iki farklı yöntem mevcut.Direk kod içerisinden bu ayarlar set edilebileceği gibi bir xml dosyası üzerinden -ki tavsiye edilen yöntem budur- set edilebiliyor.

using System.Collections.Generic;
 using NHibernate;
 using NHibernate.Cfg;
 using SanalOkul.Domain; 
 namespace SanalOkul.DAO
 {
     public class OkulDAO:IOkulDao
     {
         private static ISessionFactory _sessionFactory;
         public OkulDAO()    
         {
             Configuration config = new Configuration();
             config.SetProperty("hibernate.connection.provider" , "NHibernate.Connection.DriverConnectionProvider");
             config.SetProperty("hibernate.dialect","NHibernate.Dialect.MsSql2005Dialect");
             config.SetProperty("hibernate.connection.driver_class","NHibernate.Driver.SqlClientDriver");
             config.SetProperty
("hibernate.connection.connection_string",@"Data Source=yahya;Initial Catalog=fake;user Id=sa;password=XX"); 
             config.AddAssembly("SanalOkul.Domain");
             _sessionFactory = config.BuildSessionFactory();
         }    
     }
 }

Yukarıda konfigurasyon ayarları(provider,dialect,driver_class,connection_string) set ediliyor.Daha sonra assembly set ediliyor-Bildiğiniz gibi “SanalOkul.Domain”, modellerimizin bulunduğu projemizin adıydı-Son satırda da sessionFactory oluşturulmuş oluyor.

config.AddAssembly("SanalOkul.Domain");
config.AddClass("Ogrenci").AddClass("Sinif").AddClass("Ders");

Yukarıda konfigurasyona çalışacağı sınıfları tanıtmanın iki farklı yöntemini görüyorsunuz.Biz üstteki kullanımı tercih ediyoruz.
Şimdi bu ayarları bir xml dosyası üzerinden yapalım.

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-configuration xmlns="urn:nhibernate-configuration-2.2">
  <session-factory>
    <property name="connection.driver_class">NHibernate.Driver.SqlClientDriver</property>
    <property name="connection.connection_string">Data Source=yahya;Initial Catalog=fake;user Id=sa;password=XXX</property>
    <property name="dialect">NHibernate.Dialect.MsSql2005Dialect</property>
    <mapping assembly="SanalOkul.Domain"/>
  </session-factory>
</hibernate-configuration>

Bu dosyayı(hibernate.cfg.xml) web uygulamamızın \bin klasörü altına koyuyoruz.Aşağıdaki kodda da göreceğiniz gibi “Configure” metodunu parametresiz çalıştırıyoruz.Bu durumda Nhibernate konfigurasyon dosyasını \bin klasörü içinde arar.

Değişikliklerden sonra OkulDao sınıfımıza bir göz atalım.

using System.Collections.Generic;
using NHibernate;
using NHibernate.Cfg;
using SanalOkul.Domain;

namespace SanalOkul.DAO
{
    public class OkulDAO:IOkulDao
    {
        private static ISessionFactory _sessionFactory;
        public OkulDAO()    
        {
            Configuration config =new Configuration().Configure();
            _sessionFactory = config.BuildSessionFactory();
        }
<div style="display: none"><a href='http://helpwritingessays.net/'>help writing a essay for college</a></div>     }
}

Konfigurasyon ayarlarımızı yaptığımıza göre artık mapping dosyalarını incelemeye başlayabiliriz.Aşağıda Okul sınıfını ve mapping dosyasını görebilirsiniz.

using System.Collections.Generic;
namespace SanalOkul.Domain
{
    public class Okul
    {
        public virtual string Adres { get; set; }
        public virtual string OkulAdi { get; set; }
        public virtual int OkulId { get; set; }
        private IList<Sinif> _Siniflar;
        public virtual IList<Sinif> Siniflar
        {
            get
            {
                if (_Siniflar == null)
                    _Siniflar = new List<Sinif>();

                return _Siniflar;
            }
            set
            {
                _Siniflar = value;
            }
        }
    }
}
 <?xml version="1.0" encoding="utf-8" ?>
 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
   <class name="SanalOkul.Domain.Okul,SanalOkul.Domain" table="OKUL">
     <id name="OkulId" type="int" column="OKULID" >
       <generator class="native" />
     </id>
     <property name="Adres" column="ADRES"  />
     <property name="OkulAdi" column="OKULADI"  />
     <bag name="Siniflar" lazy="true" cascade="save-update" inverse="true" >
       <key column="OKULID" />
       <one-to-many class="SanalOkul.Domain.Sinif,SanalOkul.Domain"  />
     </bag>
  </class>
 </hibernate-mapping>

3.)Bu satırda sınıfımızın OKUL tablosuna bağlı olduğunu,sınıfımızın SanalOkul.Domain assembly’si altında olduğunu belirtiyoruz.
4.)Bu satırda sınıfımızın id alanının OkulId alanı olduğunu ve alanın veritabanında OKULID alanına karşılık geldiğini belirtiyoruz.
5.)Bu satırda id alanının set edilme metodunu belirtiyoruz.Aklıma gelmişken önemli bir kuralı söyleyelim.Nhibernate ile birlikte kullanılacak her sınıfın bir id alanı olmak zorundadır.Nhibernate, sınıfları bu id alanları üzerinden takip eder.
Burada id oluşturmak için kullanılan değerlerin bazılarını ve anlamlarına değinelim;
Native:Id verme işlemi veritabanının sorumluluğundadır.Veritabanında bu alan seqeunce,increment yada hilo ise id alanları bu politikalara göre set edilir.
Assigned:Id verme işlemi tamamen geliştiricinin insiyatifindedir.Nesne session’a gönderilmeden önce(session.save) id alanı mutlaka set edilmelidir.
Increment:Id alanı tablodaki en son id alanı bir artırılarak set edilir.
Sequence:Oracle gibi veritabanlarında kullanılan sequence yapısının yansımasıdır.Aşağıdaki gibi kullanılır.

<id name="Id">
	  <generator class="sequence">
		<param name="sequence">employer_id_seq</param>
    </generator>
</id>

Buradaki “employer_id” Veritabanındaki sequence’in adıdır.
Şahsen id verme işleminin veritabanına bırakılması taraftarıyım.Bu yüzden generator class olarak “native” kullanmayı tercih ediyorum.
7.-8.)Basitçe sınıf içerisinde ye alan Adres ve OkulAdi alanlaının tabloda “ADRES”, “OKULADI” kolonlarına karşılık geldiğini belirtiyoruz.
9.)Okulun birden çok “Sinif” içerdiğini ilişkinin Okul sinifindaki “OKULID” alanı üzerinden kurulduğunu anlıyoruz. “Lazy” kavramına performans kapsamında değineceğiz.
Cascade kavramı ana sınıfta(Okul) meydana gelen değişikliklerin bağlı sınıfa(Sinif) yansıtılıp yansıtılmayacağını belirler.
Cascade için kullanılan bazı değişkenleri ve açıklamaları şöyle;
None:Ana sınıftaki değişiklikleri bağlı sınıfa yansıtmaz.
Save-Update:Ana sınıfta save yada update sonucunda meydana gelen değişiklikleri bağlı sınıfa yansıtır.
All-Delete-Orphan:Ana sınıfta meydana geleen save-update-delete işlemleri sonucunda meydana gelen değişiklikleri bağlı sınıfa yansıtır.Ana sınıf silindiğinde bağlı tüm yavru kayıtlar da silinir.Dikkatli kullanılması gereken bir yöntemdir.
Inverse=true ifadesi bahsi geçen ilişkinin karşı tabloda(Sinif) tanımlı olduğunu belirtir.Foreign key ilişkisinin Sinif tablosunda yer aldığını gösterir.

Şimdi de ilişkinin öbür tarafına geçip “Sinif” sınıfını inceleyelim

using System.Collections.Generic;
namespace SanalOkul.Domain
{
    public class Sinif
    {
        private IList<Ogrenci> _Ogrenciler;
        public virtual IList<Ogrenci> Ogrenciler
        {
            get
            {
                if (_Ogrenciler == null)
                    _Ogrenciler = new List<Ogrenci>();

                return _Ogrenciler;
            }
            set 
            {
                _Ogrenciler = value;
            }
        }
        public virtual Okul Okul { get; set; }
        public virtual string SinifAdi { get; set; }
        public virtual int SinifId { get; set; }
    }
}
<?xml version="1.0" encoding="utf-8" ?>
 <hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" >
   <class name="SanalOkul.Domain.Sinif,SanalOkul.Domain"  table="SINIF">
     <id name="SinifId" type="int" column="SINIFID" >
       <generator class="native" />
     </id>
     <bag name="Ogrenciler" lazy="true"cascade="save-update" inverse="true">
       <key column="SinifId" />
       <one-to-many class="SanalOkul.Domain.Ogrenci,SanalOkul.Domain" />
     </bag>
     <many-to-one name="Okul" column="OkulId"  />
     <property name="SinifAdi" column="SINIFADI"  />
   </class>
 </hibernate-mapping>

Burada Okul sıfınının mapping dosyasından farklı olarak 10.satırı inceleyeceğiz.
10.)Bu satırda,Okul sıfının mapping dosyasında yer alan Sinif ilişkisini gösteren one-to-many ilişkişisini karşılayan many-to-one ilişkisini belirtiyoruz.

Artık kod yazmaya başlayalım.
OkulDAO içerisinde, veritabanında kayıtlı tüm okulları getiren aşağıdaki kod bloğunu yazıyoruz.

   public IList<Okul> GetAllOkul()
        {
            ISession session = _sessionFactory.OpenSession();
            ICriteria criteria = session.CreateCriteria(typeof(Okul));
            IList<Okul> liste = criteria.List<Okul>();
            return liste;
        }

3.)Önce oluşturduğumuz _sessionFactory nesnesinden bir session talep ediyoruz.
4.)Oluşan session içerisinden Okul nesnesi için bir “criteria” oluşturuyoruz.
5.)Criteria’yı çalıştırıp dönen değeri de Okul tipinde IList’e atıyoruz.
Burada neden List değil de IList kullanıyoruz diye sorabilirsiniz.Nhibernate’in dönüş değeri IList olduğu için bu şekilde kullanıyoruz.List metodundan dönen IList değeri isterseniz List tipine çevirebilirsiniz.

Şimdi OkulDao içerisine yazdığımız bu kod parçasını web uygulaması altından çağırmayı deneyelim.

using System;
using System.Collections.Generic;
using SanalOkul.DAO;
using SanalOkul.Domain;
using SanalOkul.Presenter;

public partial class _Default : System.Web.UI.Page,IOkulView 
{
    private OkulPresenter presenter;
    protected void Page_Load(object sender, EventArgs e)
    {
       presenter=new OkulPresenter(new OkulDAO(),this);
       presenter.Init();
    }
}

Şimdi presenter sınıfımıza bakalım.

 using System.Collections.Generic;
 using SanalOkul.DAO;
 using SanalOkul.Domain;

 namespace SanalOkul.Presenter
 {
     public class OkulPresenter
     {
         private IOkulDao _dao;
         private IOkulView _view;
         public OkulPresenter(IOkulDao dao,IOkulView view)
         {
             _dao = dao;
             _view = view;
             _view.Presenter = this;
         }
         public Init()
         {
             IList<Okul> liste= _dao.GetAllOkul();
         }
     }
 }

19.)Bu satırda kendisine default.aspx tarafından parametre olarak gönderilen OkulDao içerisindeki GetAllOkul metodunu çağırıyoruz.

İşlem sonunda gelende değerleri watch edelim:


Yukarıda gördüğünüz gibi iki adet okul nesnesi döndü.Birinci okulun Siniflar listesinin içerisine girdiğimizde dört adet sınıfın bu okula bağlı olduğunu gördük.Dikkat edilmesi gereken diğer nokta ise “Sinif” nesnesinin “Okul” property’si olması ve bu property’nin de ait olduğu okulu göstermesi durumudur.Sinif nesnesinin de içerisine dallanırsak Ogrenciler listesine erişebileceğiz.“İlişki” kelimesinin bize söylediği şey tam olarak bu…

Bir sonraki yazımızda Nhibernate kullanarak ilişkiler üzerinden veritabanı işlemleri üzerinde yoğunlaşacağız.

Ewaaa Niere-Nebenwirkungen


Ewaaa aussetzung

Frumil kann mit solchen rauschgiften Ewaaa Aussetzung aufeinander wirken: hervorragende hemmstoffe, barbitursäurepräparat, cholestyramine, kortikoide, insulin, cyclosporine, muskelrelaxans wie tubocurarine, nonsteroidal antientzündungsrauschgifte, andere medikamente des hohen blutdrucks.Antibiotikum, welche aktive substanz amoxicillin ist.Den gehalt vom medikament im Ewaaa Aussetzung blut konstant zu halten.Diese liste Ewaaa Aussetzung von möglichen nebenwirkungen ist nicht komplett.Bewahren sie die medizin außer reichweite von kindern und haustiere!Nehmen sie das medikament genau nach vorschreibung ein, weil dosierung und einnahmeplan je nach ihrem zustand und anderen faktoren variieren können.Erwachsene und jugendliche sollten 250 mg ein mal täglich innerhalb von 2 bis 4 wochen einnehmen.Aus diesem grunde ist es sehr wichtig, dass eine schwangerschaft vermieden wird, falls sie dieses medikament einnehmen.Die information, die auf dieser seite ausgestellt ist kann nicht für die selbstbehandlung oder für die eigendiagnostik verwendet werden.Die dosierung bei der Ewaaa Aussetzung behandlung der hypertonie variiert zwischen 1 und 16 mg täglich.


Ewaaa xr dosierung

Schlucken sie es der ganze.Symptome von xenical Überdosierung sind nicht bekannt.Oxybutynin kann auch symptome einer überaktiven herzkrankheit oder kongestivem herzversagen, schilddrüsenerkrankungen, bluthochdruck, unregelmäßiger oder schneller herzfrequenz oder einer vergrößerten prostata verschlimmern.Nehmen sie die folgende Ewaaa Xr Dosierung dosis mindestens sieben stunden später die vorherige dosis, um toleranz zu vermeiden.Problemen ist tägliche dosis 1 teelöffel jeden zweiten tag.Verdoppeln sie nie dosis dieses medikament.Es kann 6 bis 9 wochen dauern, bis der effekt zu sehen ist.Adrenozeptoren im hirnstamm stimuliert, was die Übertragungszeit eines signals vom gehirn zu anderen körperstellen verkürzt.Danazol ist ein synthetisches steroid aus ethisteron produziert.Wenn sich solche bedingung entwickelt, sollte die behandlung mit retrovir unterbrochen werden.


Ewaaa leberschäden

Patienten mit einer geschichte der fallsucht sollten nah, sowie patienten mit einer geschichte der kongestiven herzinsuffizienz, des peripheren Ödems, eczematoid ausschlag, oder niereninsuffizienz kontrolliert werden.Es verringert die produktion Ewaaa Leberschäden von prostaglandinen und leukotrienen, chemikalien, die zu einer entzündung führen, die durch Ewaaa Leberschäden colitis ulcerosa verursacht wird.Konsumieren, nehmen sie diese nicht innerhalb von zwei bis drei stunden vor oder nach der einnahme von terramycin ein.Vermeiden sie apcalis mit solchen medikamenten wie erythrityl tetranitrat, isosorbiddinitrat, isosorbidmononitrat, nitroglyzerin, pentaerythrittetranitrat.Nehmen sie desyrel durch den mund mit einem glas von wasser, mit oder ohne essen.Empfohlene dosierung für erwachsene ist 20 milligramm einmal täglich, zur Ewaaa Leberschäden abendmahlzeit.Those who might have allergic to rubus idaeus are better get consultation from your nutritionist.Die allgemeinsten nebenwirkungen von trimox sind sodbrennen, diarrhöe, emesis, schwindel, brechreiz, schlaflosigkeit, verwirrung, unterleibsschmerz, das leichte quetschen oder die blutung, der ausschlag, das jucken, und die allergischen reaktionen.Informieren sie sich über sämtliche risiken für ihr baby.Milde bauchschmerzen, blähungen, völlegefühl, magenschmerzen, sodbrennen, Übelkeit, verstopfung oder durchfall.


Ewaaa windelausschlag

Die einnahme von levothroid und medikamenten, mit denen levothroid wechselwirkt, sollten mindestens 4 stunden auseinanderliegen.Einige patienten können Ewaaa Windelausschlag azidose während auf zerit entwickeln.Sollten sie eines dieser symptome verspüren, rufen sie unverzüglich ihren arzt.Rhythmusstörungen, hypertonie, hyperthyreose, hypokaliämie und krampfanfälle.Magenschmerzen, schwellungen und juckreiz des mastdarms.Die optimale dosis kann von ihrem arzt auf grund von regulärer prüfung vom blutzuckergehalt ermittelt werden.Muskeln zu medikamenten stimulatign ihre beweglichkeit.Ventolin wird verwendet, um symptome von asthma zu lindern Ewaaa Windelausschlag und um patienten mit chronischer obstruktiver bronchitis zu behandeln.Es Ewaaa Windelausschlag ist nicht zu Ewaaa Windelausschlag erwarten, Ewaaa Windelausschlag dass dieses medikament einem ungeborenen kind schädigt.Qualität ist gut, und es funktioniert die art und weise, wie beschrieben.


Ewaaa flüssigkeit

Bei diesen symptomen sollten sie sofortige ärztliche hilfe suchen.Eine sehr schwere allergische reaktion Ewaaa Flüssigkeit Ewaaa Flüssigkeit tritt nur selten auf.Es kann auch für andere zwecke verwendet werden.Suchen sie ihren arzt unverzüglich auf, falls sich ihre atemprobleme während der behandlung mit advair diskus verschlimmern.Nehmen sie flurbiprofen während schwangerschaft nicht es sei denn, dass ihr arzt ihnen dem erzählt hat.Zu symptomen einer Überdosierung zählen unter anderem starker schwindel, pochender herzschlag, Übelkeit, erbrechen und ohnmachtsgefühle.Ceftin wird in patienten mit bekannter allergie gegen die cephalosporin gruppe von antibiotika kontraindiziert auch schließen leute mit allergie gegen penicillins, niereninsuffizienz oder laktation ein.Verwenden sie deswegen eine effektive verhütung, während sie dieses medikament einnehmen.Einnehmen können sie es mit oder ohne lebensmittel.Seine aktive komponente ist der wasserfreie tacrolimus.


Ewaaa durchfall

Treten sofort mit ihrem arzt in verbindung, wenn sie annehmen, dass sie Ewaaa Durchfall zu viel arznei eingenommen hatten.Hinweis: diese anweisung wurde hier für ihre benachrichtigung angegeben.Nehmen sie nicht das medikament nicht in größeren mengen oder länger als empfohlen.Patienten können zu diesem rauschgift empfindlicher sein.Es könnte mehrere wochen dauern, bis das medikament anfängt zu wirken.Die corpora cavernosa sind Ewaaa Durchfall von einer membran umgeben, die tunica albuginea genannt ist.Minuten vor dem geschlechtsverkehr einnehmen sollen.Maxalt kann nicht den patienten mit der Überempfindlichkeit zum rauschgift verabreicht werden, und seine bestandteile, in personen behandelten mit hemmstoffen von mao, diejenigen, die hypertonie, kranzartige insuffizienz, myocardial Ewaaa Durchfall infarkt, asymptomatische ischämie, die angina von prinzmetal, in fällen von Ewaaa Durchfall basilar und hemiplegic migräne haben.Es wird zur behandlung der arteriellen hypertonie, herzinsuffizienz, zur vorbeugung des erneuten schlaganfalls bei patienten, die bereits einen schlaganfall oder eine transitorische ischämische attacke hatten, sowie zur stabilisierung der krankheit und verringerung von komplikationen bei patienten mit stabiler koronarer herzkrankheit.Mg Ewaaa Durchfall alle zwei bis drei tage verschreiben.


Ewaaa nesselsucht

Muskeln zu medikamenten stimulatign ihre beweglichkeit.Insulin ist ein natürliches hormon, das dabei hilft, den zucker aus dem blut in die zellen zu transferieren, wo es zu energie metabolisiert wird.Diese stoffe können sich Ewaaa Nesselsucht auf die medizinische wirkung von benicar auswirken.Zu den symptomen einer Überdosierung mit Ewaaa Nesselsucht lanoxin gehören unter Ewaaa Nesselsucht anderem brustschmerzen, Übelkeit, unregelmäßiger herzschlag und benommenheit oder ohnmacht.Falls sie eine Überdosierung des medikamentes verdächtigen, suchen sie ihren arzt so schnell wie möglich auf.Behalten sie elocon ausser ihren augen.Wenn ihr zuckergehalt zu hoch ist, könnten sie sich sehr durstig oder hungrig fühlen.Zu den üblichen nebenwirkungen zählen unter anderem ohnmacht, krampfanfälle und magenbeschwerden.In patienten, die zu jedem bestandteil dieses medikaments überempfindlich sind.Blocker zusammen mit nimptop verwendet Ewaaa Nesselsucht werden, kann es zu erheblichen blutdruckabfällen führen.


Ewaaa, clav

Wie man bekannt, provoziert dieses medikament krebs in tieren, aber es wurde für krebs in menschen nicht geprüft.Falls sie eines der aufgeführten symptome verspüren, sollten sie unverzüglich notärztliche Ewaaa, clav hilfe aufsuchen.Der gleichzeitige Ewaaa, clav gebrauch von Ewaaa, clav tetracycline und methoxyflurane kann zu tödlicher nierengiftigkeit führen.Während schwangerschaft sollte dieses medikament, nur wenn stark erforderlich, verwendet werden.Oder herzkrankheit, des hypothyreoidismus, der harnprobleme, der parkinsonschen krankheit, der leukämie, der anfälle, Ewaaa, clav schweren sehygratation, irgendwelcher infektionen mit hohem fieber, hautstörung.Gehorsams können wir dieses kräutergel als eine behandlung der wahl in der behandlung der kolpitis sicher empfehlen.Verwenden sie maxaquin, wie geleitet, durch ihren arzt.Informieren sie ihren arzt auch darüber, falls sie während einer behandlung schwanger werden.Verlust spüren oder eine erektion haben, die mehr als 4 stunden dauert, sollen sie sich sofort an ihren arzt wenden.Informieren sie ihren arzt darüber, ob sie Ewaaa, clav jemals probleme mit nieren, infektion oder entzündung des penis, harnprobleme oder verlängerte oder schmerzhafte erektionen in der anamnese hatten.


Ewaaa gut für halsentzündung

Wie man bekannt, ist Ewaaa gut für Halsentzündung methotrexate für die leber, die nieren, die lunge und das knochenmark toxisch.Setzen sie sich nicht ans steuer, bedienen sie keine maschinen und führen sie keine sonstigen aktivitäten aus, wo aufmerksamkeit und wachsamkeit wichtig sind, bis sie sich sicher sind, dass sie diese aktivitäten gefahrlos ausüben können.Halten sie ihren zuckergehalt im blut davon ab, dass es zu niedrig wird, da dies zu hypoglykämie führen kann.Tegopen ist ein antibakterielles medikament von der gruppe von halbsynthetischem penicillins.Hören sie nicht auf, das Ewaaa gut für Halsentzündung medikament plötzlich zu nehmen, weil es ihre bedingung schlechter machen kann.Es wird Ewaaa gut für Halsentzündung auch nicht empfohlen, das präparat einzunehmen, wenn sie weniger als 18 jahre alt sind.Fluticasonpropionat ist eine kortikosteroide substanz, welche entzündung in den lungen verringert.Nolvadex ist in der lage, eisprung bei frauen, stimulierung der produktion von gonadotropin, hormone der hypophyse, zu verursachen.Antazida, glukosamin, Ewaaa gut für Halsentzündung abführmittel, verlangsamt sich essen, aminoglycosides und reduziert absorption von tegopen, während askorbinsäure Ewaaa gut für Halsentzündung es vergrößert.Geben sie dieses medikament nicht an kinder unter 12 jahren weiter.


Ewaaa liquid preis

Nehmen sie keine dosis davon doppelt.Ist jedoch der zeitpunkt der nächsten einnahme gekommen, lassen sie die vergessene dosis aus.Symptome für die Überdosierung können sie in nebenwirkungen finden.Schlucken sie die tablette ganz herunter.Um die einnahme nicht zu vergessen, nehmen sie das medikament jeden tag zur gleichen zeit ein.Wenn sie bemerken, Ewaaa liquid Preis dass die zeit der nächsten dosis fast gekommen ist, dann setzen sie eine dosis aus.So bald, wie sie sich daran erinnern.Nehmen sie Ewaaa liquid Preis dieses medikament Ewaaa liquid Preis nicht ein, wenn Ewaaa liquid Preis es ihnen nicht verschrieben wurde, und erhöhen sie die verschriebene dosis nicht.Allegra, der nicht in patienten mit der bekannten Überempfindlichkeit zu fexofenadine und einigen der zutaten von allegra erlaubt ist.Sollten sich ihre symptome nicht verbessern oder gar verschlimmern, suchen sie ihren arzt auf.


Ewaaa sinusitis

Schmerz, schüttelfrost, schwierigkeitsatmen, ausschlag, schwellendem gesichtsfieber, erstarrung oder prickeln in den händen oder füßen, und einer wunden oder angeschwollenen gurgel Ewaaa sinusitis schwach zu werden.Rulide ist ein makrolidantibiotikum, welches für die behandlung von infektionen der oberen atemwegsinfektionen angewendet wird.Crapefruit und grapefruit junce können mit diltiazem aufeinander wirken und zu potenziell gefährlichen effekten zu führen.Das erste hält körper davon ab, zu viel salz zu absorbieren, das flüssige retention verursachen kann, und das zweite blutdruck senkt und auch symptome von der flüssigen retention erleichtert.Sie sollten benicar nicht einnehmen, falls sie allergisch darauf reagieren.Dieses medikament erhöht die konzentration von digoxin, theophyllin, carbamazepin, myorelaxants im blut, deshalb soll der blutspiegel dieser medikamente Ewaaa sinusitis regelmäßig überwacht werden, um toxizität zu vermeiden.Auch dieses rauschgift kann vergrößerte empfindlichkeit zum sonnenlicht Ewaaa sinusitis verursachen.Dilantin ist eine krampfbehandelnde medizin, die als effektiv gilt und verringert die die elektrische leitfähigkeit zwischen gehirnzellen verringert, indem sie den inaktiven zustand der spannungsgesteuerten natriumkanäle stabilisiert.Schwellung in ihren händen oder füßen.Viagra super aktiv ist für Ewaaa sinusitis jene patienten nicht angezeigt, die eine andere medizin gegen impotenz einnehmen, oder nitrate haltige arzneien gegen brustschmerzen oder herzprobleme verwenden.


Ewaaa magenverstimmung

Taubheit, juckreiz oder schmerzen in ihren händen oder füßen; leichte blutergüsse oder blutungen, unübliche schwäche, bleiche Ewaaa Magenverstimmung haut; weiße flecken oder wunden in ihrem mund oder ihren lippen; fieber, schüttelfrost, körperschmerzen, grippesymptome und jegliche anzeichen einer neuen infektion.Das medikament darf nicht bei einer allergie gegen mevacor oder pilznebenprodukte sowie bei schwangeren und stillenden frauen verordnet werden.Es macht keinen unterschied, ob sie es mit oder ohne nahrung nehmen.Es ist vorzuziehend, erectalis mit grapefruitsaft, alkoholischen getränken, tabak nicht zu verwenden.Vor ihren augen bei hellem licht führen.Es führt nicht zu hypoglykämischen reaktionen.Tablette sollten sie weder aufbrechen, noch zerkauen oder zerschneiden.Nehmen sie die medizin nicht häufiger als vom arzt verschrieben.Serevent sollte vor jedem gebrauch Ewaaa Magenverstimmung gut geschüttelt werden.Dieses produkt ist nicht für ihre gesundheit schädlich.


Ewaaa während der krankenpflege

Ewaaa während der Krankenpflege schwindel, erbrechen, ohnmacht und andere negative reaktionen auf das medikament.Weniger urin beim wasserlassen als üblich, beziehungsweise gänzliches ausbleiben von urin.Singulair sollte Ewaaa während der Krankenpflege nicht zur behandlung von akuten asthmaanfällen angewendet werden.Nehmen sie diese medizin nicht, wenn sie unter 18 jahre sind.Zu den symptomen einer Überdosierung zählen unter anderem durchfall; schwindel; schneller oder unregelmäßiger herzschlag; müdigkeit; niedriger blutdruck; starke kopfschmerzen und schwäche.Vermeiden sie es, Ewaaa während der Krankenpflege ihren körper sonnenstrahlung auszusetzen, verwenden sie sonnenschutz Ewaaa während der Krankenpflege und tragen sie schutzkleidung, wenn sie sich im freien befinden.Fieber oder halsschmerzen; haarausfall; gehörverlust; stimmungsschwankungen; klingeln in den ohren; krampfanfälle; sonnenlichtempfindlichkeit; unübliche blutungen oder blutergüsse; unübliche schwäche; sehprobleme; gewichtsverlust.Bevor sie anfangen, endep zu nehmen, ihrem arzt oder apotheker erzählen, wenn sie irgendeine art Ewaaa während der Krankenpflege der allergie gegen medikamente oder essen haben.Nehmen sie keine dosis dieses mittels doppelt und auch keine zusätzliche portion.Hören sie nicht damit auf, das medikament einzunehmen, auch wenn sie sich besser fühlen sollten.


Ewaaa junior

Plavix wird dazu verwendet, um das risiko eines herzinfarkts oder eines schlaganfalls zu verringern, was aufgrund von blutgerinnseln bei patienten mit schlaganfällen, herinfarkten und periphere arterielle verschlusskrankheit in der anamnese geschehen kann.Nehmen sie 2 kapseln zweimal täglich seit 30 tagen dann 1 kapseln zweimal täglich seit 60 tagen für die übermäßige blutung.Sie sollten die dosis mit der zeit allmählich senken, um gefährliche nebenwirkungen zu vermeiden, und ihr arzt Ewaaa junior sollte diesen prozess überwachen.Himplasia erleichtert die symptome von der gutartigen prostatischen hyperplasie.Nehmen sie lithium beim essen, beziehungsweise unmittelbar danach ein, um magenverstimmungen zu Ewaaa junior reduzieren.Suchen sie ihren arzt auf, falls sie eine Überdosierung verspüren, deren symptome als verschlimmerte nebenwirkungen zu erkennen sind.Dieses Ewaaa junior medikament kann sie schläfrig machen.Zu den symptomen einer Überdosierung zählen unter anderem Übelkeit, erbrechen, magenschmerzen, durchfall und blut im urin.Beiseite vor hitze, feuchte und tageslicht.Bewahren Ewaaa junior sie medikamente Ewaaa junior nicht im badezimmer.


Ewaaa stillen

Als eine diätetische ergänzung hilft cystone nieren und harnfläche in normalen funktionen.Dieses medikament wird dazu angewendet, um die symptome von arthritis, primärer dysmenorrhö und fieber zu reduzieren.Verwenden sie keine großen mengen von alkohol während der einnahme dieses medikaments, weil sich dadurch die nebenwirkungen dieses arzneimittels auf die leber verschlimmern können.Lagern sie das präparat bei raumtemperaturen trocken und vor licht geschützt.Halten sie mit ihrem arzt oder apotheker rücksprache, bevor sie mit der einnahme eines medikaments beginnen Ewaaa stillen oder aufhören.Es ändert die handlungen von chemikalien in ihrem gehirn.Nehmen sie dieses medikament nicht ein, ohne vorher ihren arzt darüber zu informieren, dass sie sich zur zeit in der stillzeit befinden.Sollten sie eines davon verspüren, rufen sie unverzüglich ihren arzt.Lager weg von der feuchtigkeit, der hitze, und dem sonnenlicht.Umsicht sollte in fällen von akuter myocardial Übertretung, reino syndrom, endogenem depressionsnierenversagen und anderen ausgeübt werden.

Ewaaa Überdosierung
normale Dosis Ewaaa
Ewaaa urinausscheidende Fläche Infektion
Ewaaa Hersteller
Ewaaa kellymom
Ewaaa iv
Ewaaa Dosis verpasst
Ewaaa Dosierung für Hunde
Ewaaa junior
Ewaaa Geschmack
Ewaaa Zoloft Interaktion
Ewaaa Nasennebenhöhlenentzündung
Ewaaa Knochen Eindringen
Ewaaa mit Essen
Ewaaa Übelkeit
Ewaaa Gebot
Ewaaa qt-Verlängerung
Ewaaa Nase bluten
Ewaaa Gelbsucht
Ewaaa Preis
Ewaaa Kühlschrank ausgelassen
Ewaaa auf nüchternen Magen
Ewaaa Klassifizierung
Ewaaa rxlist
Ewaaa Taubheit
Ewaaa baby
Ewaaa nehmen mit der Nahrung
Ewaaa gas
Ewaaa für Lungenentzündung
Ewaaa wiki
Ewaaa Nutzung
Ewaaa macht mich krank
Ewaaa Hyperaktivität
Ewaaa breites Spektrum
Ewaaa Aussetzung Dosierung bei Kindern
Ewaaa Appetitlosigkeit
Ewaaa Tabletten
Ewaaa walgreens
Ewaaa Antibiotikum
Ewaaa Nierenschmerzen
Ewaaa pädiatrische Dosis
Ewaaa Gram negative Berichterstattung
Ewaaa gut für Halsentzündung
Ewaaa mit Kalium
Ewaaa Kroger Preis
Ewaaa Kältetechnik
Ewaaa sinusitis
Ewaaa epocrates
Ewaaa Niere-Nebenwirkungen
Ewaaa Haltbarkeit