Posts Tagged ‘NHibernate’
NHibernate’te Char tipleri ile çalışmak
NHibernate string olarak tanımladığımız özellikleri veri tabanında nvarchar veya varchar2 gibi tiplerde oluşturuyor veya arıyor. ama benim bir projemde denk geldiği şekilde char türündeki bir tablo alanı ile çalışmak gerektiğinde ne yapabiliriz diye bir araştırma yaptığımda açıkçası biraz hayal kırıklığına uğradım. Nesnesel olarak olayı çözemiyoruz gibi. Bunun yerine sql düzeyinde bir çalışma yapmak lazım. Şöyle ki:
1 | public virtual string TelephoneNumber {get; set; } |
şeklinde tanımlanmış alanım için,
1 2 3 4 | Map(x=> x.TelephoneNumber) .Length(4) .CustomSqlType(“CHAR(10)”) .Nullable(); |
şeklinde bir mapping satırı yazmam gerekmekte. allahtan char tipi bütün veri tabanı sistemlerinde aynı kullanıma sahipte herhangi bir problem çıkarmadan çapraz platform çalışabiliyor.
NHibernate Fluent ile tek tablodan birden fazla nesne
Diyelim ki bir sınıftan türemiş birden fazla sınıfınız var. Ve bunları fluent arayüzünü kullanarak NHibernate içinde kullanmak istiyorsunuz. Bunun için öncelikle http://wiki.fluentnhibernate.org/Fluent_mapping adresini ziyaret edip, buradan bilgi edinebilirsiniz. Ancak maalesef yetersiz bir bilgiye sahip olacaksınız. Burada olay çok kısa ve yüzeysel olarak verilmiş. ben konuyu biraz daha ileri götürmek istiyorum. Öncelikle sınıflarımınızı tanımlayalım.
Önce temel sınıfımız. NHibernate bu sınıf için bir tablo üretecek.
1 2 3 4 5 6 7 8 9 10 11 12 13 | public abstract class EKayit { public virtual int KayitID { get; set; } public virtual KayitTipi KayitTipi { get; set; } public virtual string DosyaAdi { get; set; } public virtual byte[] Icerik { get; set; } public virtual string MimeType { get; set; } } |
Şimdide alt sınıflarımızı tanımlayalım.
1 2 3 4 5 | public class ESesKayit : EKayit { } public class EVideoKayit : EKayit { } public class EDigerKayit : EKayit { } |
birde dikkat ettiyseniz alt sınıfın tiplerini tutan bir enum tipimiz var. buda :
1 2 3 4 5 6 | public enum KayitTipi : byte { Ses = 1, Video = 2, Diger = 4 } |
şeklinde tanımlanmış olsun. Şimdi gelelim mapping sınıflarımıza. Önce EKayit ile başlıyoruz :
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 | public class EKayitMap : ClassMap<EKayit> { public EKayitMap() { Table("TKayit"); Id(x => x.KayitID) .Not.Nullable() .GeneratedBy.Native(); DiscriminateSubClassesOnColumn<byte>("KayitTipi", (byte)KayitTipi.Ses) .CustomType<KayitTipi>() .Not.Nullable(); Map(x => x.DosyaAdi) .Length(100) .Not.Nullable(); Map(x => x.Icerik) .Not.Nullable() .Length(int.MaxValue) .LazyLoad(); Map(x => x.MimeType) .Length(50) .Not.Nullable(); } } |
Dikkat edilmesi gereken en önemli yer DiscriminateSubClassOnColumn tanımı. Burada yanlış tanımlama yaptığınızda şu türde hata mesajları alabiliyorsunuz :
1 2 | [ArgumentException: Requested value 'CD.DataLayer.Entities.EKayit' was not found.] [MappingException: Could not format discriminator value to SQL string of entity CD.DataLayer.Entities.EKayit] |
Bu hataları alınca internette arayışa geçtim. sonunda http://stackoverflow.com/questions/326174/nhibernate-mapping-with-a-class-hierarchy-whose-base-class-is-abstract-and-the-d adresi aradığımı bulmamı sağladı.
Önce problemi anlatayım : Entity sınıfından da gördüğünüz gibi, KayitTipi alanını KayitTipi enum türünden tanımlamışım. Bu özel bir tip olduğu için burada nhibernate’e bu tipin neye karşılık geleceğini bildirmek gerekiyor. bunun için 2 yöntem var esasında. 1. yöntem DiscriminateSubClassOnColumn metodunun jenerik halini kullanmak DiscriminateSubClassOnColumn<byte> şeklinde. böylece sisteme bu elemanın tipini bildiriyorsunuz. 2. yöntem ise DiscriminateSubClassOnColumn metoduna 2. parametreyi atamak. bu parametre yine jenerik metodun tipini belirlediği için esasında 1. yönteme çıkıyor olay. Ben yukarıda bunun ikisini bir arada kullandım.
Şimdi gelelim alt sınıfların mappinglerine.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 | public class ESesKayitMap : SubclassMap<ESesKayit> { public ESesKayitMap() { DiscriminatorValue((byte)KayitTipi.Ses); } } public class EVideoKayitMap : SubclassMap<EVideoKayit> { public EVideoKayitMap() { DiscriminatorValue((byte)KayitTipi.Video); } } public class EDigerKayitMap : SubclassMap<EDigerKayit> { public EDigerKayitMap() { DiscriminatorValue((byte)KayitTipi.Diger); } } |
Burada önemli olan kısım ise alt sınıfların ClassMap’ sınıfından değilde, SubclassMap sınıfından türetilmeleri. Ayrıca ayırıcı alanda hangi değerin olması gerektiği bu sınıfların yapıcılarında da verilmiş durumda. Tiplerin yine çevirildiğine dikkat edelim.
Böylece işlemi bitirmiş olduk.
Linq to ….
Linq dan sonra linq için ne kadar proje geliştirildiğini merak ettim. Sevgili Google da linq to şeklinde yazmaya başladığımda otomatik tamamlamada gördüğüm birkaç projeyi sizlerle paylaşmak istedim.
1. Linq to Javascript :
Javascript için linq framework’ü yazmışlar. Yoğun şekilde Javascript kullanılacaksa ve verilerle çok uğraşılması gerekiyorsa işinize yarayabilir.
Site: http://www.codeplex.com/JSLINQ
Konuya giriş için türkçe bir blog yazısı.
2. Linq to LDAP:
Active Directory veya bir ldap kaynağından veri sorgulamayı sağlayan bir yöntem.
Yöntemi açıklayan Blog yazısı.
3. DbLinq Project: Linq Provider for MySql, Oracle and PostgreSQL
Adındanda anlaşılacağı gibi linq ile desteklenmeyen veri tabanlarından en önemli 3 tanesine bağlantı sağlayan bir proje. ADO.Net Entity Framwork ile bu açıkta Microsoft tarafından kapatılmaya çalışılmakta.
Proje Sitesi: http://code2code.net/DB_Linq/
4. Linq to NHibernate:
NHibernate için Linq eklentisi nasıl yazılır. Bu blog yazısında Ayende Rahien (a.k.a. Oren Eini) bundan bahsetmektedir.
5. LINQ to Google Desktop
Google Desktop, Google’ın yerel makinada çalışan versiyonu. Dosyalarınız arasında kaybolmadan arama yapmanızı sağlamakta. Bu program için Luis Diego Fallas tarafından hazırlanmış blog yazısına bakabilirsiniz.
6. Linq to Streams (SLinq, Streaming LINQ)
Oren Novotny tarafından geliştirilen ve sürekli veri akımları üzerinde çalışan bu bileşen sayerinde gerçek zamanlı select, where ve orderby kullanılabilmektedir.
Proje Sitesi : http://www.codeplex.com/Slinq/
7. i4o – indexes for objects
Gerçekte bir linq sağlayıcısı olmayıp, linq sorgularını hızlandırmak için hazırlanmış bir linq eklentisidir. Bu eklentiyi anlatan blog yazısına buradan ulaşılabilir.
Proje Sitesi: http://www.codeplex.com/i4o
