Bu site emekli olmuştur. Arşiv amaçlı olarak BT AKADEMİ sponsorluğunda yayın hayatına devam etmektedir.




C#nedir?com
 
YAZAR HAKKINDA
Önsel Akın
Önsel Akın
http://nslkn.com
İletişme geçmek için tıklayın.
8 Makalesi yayınlanmakta.
Yazar hakkında detaylı bilgi için tıklayın.
Yayınlanan diğer makaleleri için tıklayın.
İlgili etiketler: DDD Domain Driven Design Fluent NHibernate FluentNH Linq NHibernate NHibernate Session O/RM Object Relational Mapping Persistence Genel Önsel Akın
 
YAZI HAKKINDA
Türü : Makale
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
Seviyesi : İleri
Kategori : Genel
Yayınlanma Tarihi : 5.11.2010
Okunma Sayısı : 104071
Yorum Sayısı : 24     yorum yaz
Site İçi AramaSİTE İÇİ ARAMA
Üye Girişini AçÜye GİRİŞİ
Üye girişi için tıklayın.
Kullanıcı Adı
Şifre
 
Beni her zaman hatırla
Bir hafta boyunca kullanıcı bilgilerinizi kullanıcı çıkışı yapana kadar hatırlar. (Paylaşılan bilgisayarlarda önerilmez.)
 
Şifremi / Kullanıcı Adımı unuttum.
 
.net TV RSS Serbest KÖŞE (?)
Serbest Köşede C#nedir?com üyelerinin hazırladıkları yazılar yayınlanır. Bu yazılar editör incelemesine girmeden yayınlanır.
emre TAŞ
Silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
emre TAŞ
silindi
emre TAŞ
yazının devamı >
Makale Gönder Bende Yazmak İstiyorum
.net TV RSSBlogroll
Turhal Temizer
Conda install environment.yml Package 29.3.2024
Turhal Temizer
Mac OS/X Removing CUDA 29.3.2024
Burak Selim Şenyurt
Kurumsal Yazılımcının Oyun Geliştirme ile İmtihanı 29.3.2024
Burak Selim Şenyurt
Matematik ve Oyun Programlama - Missile Command - Final 29.3.2024
  Diğer Herşey
Sponsorlar
BT Akademi
Medya Portakal
Video Hosting Sponsoru
Csharpnedir.com bir Ineta üyesidir
Uzman Abi
Her Yönüyle C# - Sefer Algan
NHibernate
 
Kapat
Sayfayı Yazdır Sık Kullanılanlara Ekle Arkadaşıma Gönder MySpace Del.Ico.Us Digg Facebook Google Mixx Reddit StumbleUpon

Başlık kısa ancak konu oldukça uzun. 2000'lerin başından beri var olmasına rağmen Türkiye'deki .Net camiasında yurtdışındaki kadar popüler olmayan ancak en güçlü O/RM seçeneklerinden biri olan NHibernate ile ilgili hızlı bir tanıtım yazısı okumak üzeresiniz.

O/RM (Object Relational Mapping) mi?

Kaçınız şimdiye veri depolama ihtiyacı olmayan bir uygulama geliştirdi? Eğer yazılım geçmişiniz benim gibi Commodore ve Amstrad dönemlerine kadar uzanmıyorsa bu soruya "ben" şeklinde cevap vermenizin düşük bir ihtimal olduğunu düşünüyorum.

Geliştirdiğimiz her yazılımda bir şekilde bir yerde veri depolama ihtiyacı duyuyoruz. XML dosyalarından, ilişkisel veritabanlarına kadar veri depolamak için birçok alternatif mevcut. Bu birçok alternatife erişip veri üzerinde işlem yapmak için yine birçok farklı teknoloji mevcut. .Net dünyasında olan birçok yazılım ekibi genelde bu alternatifler içinden Ado.Net'i, dolayısıyla DataSet, DataReader vb. nesneleri kullanmayı tercih ediyor. Tabi ki bunda yanlış olan hiçbir şey yok. Ancak durum biraz daha farklı. Şöyle ki;

Herşeyi nesnelerle düşünür, nesne olarak değerlendiririz.

Yani bir topluluk portali uygulaması geliştiriyorsak, "Üye"lerden, "Paylaşım"lardan, "Yorum"lardan vb. birçok nesneden / varlıktan bahsediyoruz demektir. Ya da bir bankacılık uygulaması ise geliştirdiğimiz, Hesap, Müşteri, Para Transferi, Kredi Kartı gibi nesnelerdir uygulamamızın kapsamını oluşturan. Bu kapsama ilgi alanı (domain), bu kapsam içinde yukarıda bahsettiğimiz her nesneye de ilgi alanı modeli (domain model) ismi verilmektedir. Çözüm gerektiren her problemin adreslendiği yer ilgi alanı modeli olmalıdır. Kredi Kartı numaralarının doğruluğunun kontrolü, hesap bakiyesi belli bir miktarın üstünde olan müşterinin "gold" müşteri olarak değerlendirilmesi gibi "iş" ile ilgili her durum bu ilgi alanı içerisinde modellenir.

Bu modelleme süreci, modellerin veri depolarında saklanma aşamasına gelindiğinde başka bir ihtiyacın ortaya çıkmasına neden olur. .Net üzerinden ilerleyecek olursak, programlama dilinde "sınıf" olan bu modeller, veri saklama ortamlarına aktarılırken tablolara, daha doğrusu tabloları oluşturan kayıtlara dönüştürülmelidirler. Yani kendi içinde her tür durumun (ya da daha gerçekçi olması açısından birçok durumun diye düzeltelim) değerlendirildiği bir sınıfın depoladığı verinin alınması, ilişkisel veritabanının anlayabileceği, saklayabileceği formata dönüştürülmesi ve depolanması gereklidir. Eğer şimdiye kadar anlattığım gibi bir ilgi alanı modeli geliştiriyorsanız ve ilgi alanı içindeki modellerinizin verisini örneğin SQL Server'da saklamak için gerekli olan dönüşüm kodlarını yazıyorsanız tebrik ederim, siz bir O/RM geliştiricisi olmuşsunuz bile.

Wikipedia'dan alınmış tam tanımı ile, O/RM, nesne yönelimli programlama dillerinde uygulanan, birbirleriyle uyumsuz tip sistemleri arasında, verinin uyumlu hale getirilmesi tekniğidir. Bu tanımı bizim anlatımımıza uyarlayacak olursak; .Net ile SQL Server tabloları birbirleriyle uyumsuz tip sistemleridir ve bizim, nesnelerden aldığımız her veriyi SQL Server uyumlu hale getirmek için yazdığımız her satır kod O/RM tekniğine işaret eden bir koddur diyebiliriz.

NHibernate'in yukarıdaki anlatımda tam olarak nereye oturduğu sanırım anlaşılmıştır. NHibernate bir O/RM çatısı. .Net ile yazdığımız sınıfların, ilişkisel veritabanı sistemleri ile eşleştirmesini (dönüştürülmesini) gerçekleştiriyor. Daha güzel bir ifadeyle, biz ilgi alanımıza ve iş kurallarımıza yoğunlaşırken, ilgi alanı modelimizin veritabanı ile ilgili olan kısmındaki tüm ağır işi NHibernate yükleniyor.

O/RM'nin M'si

NHibernate, sınıfların ilişkisel veritabanı ile eşleştirilmesini sağlıyor demiştik. O halde bu eşleştirmenin nasıl yapılması gerektiğini de NHibernate'e göstermek gerekiyor. Modellerin hangi özellikleri, veritabanında hangi kolon ile eşleşecek, modelin hangi özelliği eşlenen tablodaki anahtar kolon olacak, modeller arasındaki ilişkiler veritabanına ne şekilde yansıtılacak vb. gibi tüm eşleme kurallarının NHibernate tarafından bilinmesi gerekiyor.

Eşleme kurallarının tanımlanması için kullanılabilecek iki yöntem mevcut. Birinci yöntem -ki bu en eski ve yaygın olan yöntemdir- hbm.xml uzantılı bir xml konfigürasyon dosyası ile eşleme kurallarını belirlemek. İkinci yöntem NHibernate ile kardeş proje olan Fluent NHibernate kullanarak gerçekleştirilen eşleme gerçekleştirmek. Xml konfigürasyon dosyalarını her zaman sıkıcı ve itici bulmuşumdur, dolayısıyla bu yazıda Fluent kullanarak eşlemeleri gerçekleştireceğim.

İlgi Alanı Modeli

Fluent NHibernate içinde hazır gelen örnek proje üzerinden ilerleyeceğiz. Yazının sonunda projeyi indirebileceğiniz web adresini paylaştım. Yazı içerisinde yapacağım küçük değişiklikleri kolayca projeye uyarlayabilirsiniz. Projedeki modellerin yapısı şu şekilde:

image

İlgi alanı içinde dört model mevcut. Özellikleri şemada gördüğünüz gibi. Modelde üzerinde durulması gereken şey sınıflar arasındaki ilişkiler. Store ve Product sınıfları arasında çoka-çok (many-to-many) ilişki mevcut. Yani bir mağazada birden çok ürün bulunabilir ve bir ürün birçok mağaza stoğunda mevcut olabilir. Ayrıca Store ve Employee sınıfları arasında bire-çok (one-to-many) ilişki mevcut. Yani bir mağazada birden çok çalışan bulunabilir. Product ve Location sınıfları arasında ise biraz daha farklı bir ilişki mevcut. Bu iki sınıf arasında bir bileşim (composition) ilişkisi tanımlı. Yani ürünün depodaki koridor ve raf numarasını göstermekte olan Location sınıfı her ürünün mutlaka sahip olması gereken bir bileşen. Modeli kullanırken koridor ve raftan oluşan bu lokasyon nesnesine tek başına bir varlıkmış gibi erişebileceğiz ancak ilişkisel veritabanı açısından bakıldığında Location nesneleri için ayrı bir veritabanı tablosu oluşturulmayacak. Bunun yerine, Location sınıfına ait olan Aisle ve Shelf özellikleri, sanki Product sınıfının doğrudan özellikleriymiş gibi Product tablosunda iki ayrı kolon olarak tanımlanacak ve bu kolonlarda bilgi depolanacak.

Fluent NH ile Eşleme

Eşlemenin nasıl kodlandığına geçmeden önce model içinden bir sınıf örneği göstererek NHibernate'in bir özelliğinden bahsetmek istiyorum. Store sınıfının tanımına bakalım:

public class Store
{
  public virtual int Id { get; private set; }
  public virtual string Name { get; set; }
  public virtual IList<Product> Products { get; set; }
  public virtual IList<Employee> Staff { get; set; }

  public Store()
  {
    Products = new List<Product>();
    Staff = new List<Employee>();
  }

  public virtual void AddProduct(Product product)
  {
    product.StoresStockedIn.Add(this);
    Products.Add(product);
  }

  public virtual void AddEmployee(Employee employee)
  {
    employee.Store = this;
    Staff.Add(employee);
  }
}

Özelliklerin ve metodların virtual tanımlandığını farketmişsinizdir. Bunun nedeni lazy-loading adı verilen ve birbiriyle bağlantılı olan nesnelerin tek seferde değil ihtiyaç oldukça veritabanından çekilmesini sağlayan NHibernate özelliğinin aktif olmasıdır. Bir mağazamız (Store) ve bu mağaza içinde kayıt edilmiş 10 bin adet ürün (Product) olduğunu düşünün. Lazy-loading özelliğinin aktif olmadığı durumda, veritabanından mağazayı sorgulayıp çektiğimizde NHibernate 10 bin adet ürünü de ihtiyacımız olsa da olmasa da çekip getirecektir.

Peki neden virtual?

NHibernate lazy-loading özelliğini devreye sokmak için, NHibernate altyapısının inşası sırasında model sınıflarından türeyen, model sınıflarının sahip olduğu ve olmadığı bir takım ek özellikleri içinde bulunduran "proxy" sınıflar oluşturur ve oturum açık olduğu sürece model sınıfları yerine bu proxy sınıflar üzerinden işlem gerçekleştirir. Model sınıflarındaki özelliklerin virtual olması da, model sınıfın sahip olduğu özelliklerin proxy tarafından override edilebilmesini ve lazy-loading için gerekli olan algoritmanın proxy tarafından uygulanabilmesini sağlar.

Sınıf tanımında üzerinde durulması gereken bir diğer nokta, bire-çok ve çoka-çok ilişkiler için yapılmış olan tanımlamalar. Bir mağaza stoğunda birden çok ürün bulunabilir demiştik. Bunun karşılığı;

public virtual IList<Product> Products { get; set; }

olarak tanımlanıyor. Store sınıfının yapılandırıcısı içinde de Products listesinin oluşturulduğunu görebilirsiniz. Store ve Employee sınıfları arasında bire-çok ilişki olacak demiştik, bunun Employee sınıfındaki karşılığı ise;

public virtual Store Store { get; set; }

olarak tanımlanıyor. NHibernate, doğru eşlemeler yapıldıktan sonra tüm bu ilişkiler dahilinde kayıtların veritabanına gönderilmesini / çekilmesini gerçekleştirecek.

Şimdi eşlemelerin nasıl yapıldığına StoreMap üzerinden bakalım.

public class StoreMap : ClassMap<Store>
{
  public StoreMap()
  {
    Id(x => x.Id);
    Map(x => x.Name);
    HasManyToMany(x => x.Products)
      .Cascade.All()
      .Table("StoreProduct");
    HasMany(x => x.Staff)
      .Cascade.All()
      .Inverse();
}

}

Her model için bir eşleme sınıfı tanımlıyoruz (tamamen otomatik olarak eşlemeleri gerçekleştirmek de mümkün, belki başka bir yazıda bu özelliği inceleyebiliriz). Eşleme sınıfı ClassMap sınıfından türetiliyor ve eşleme kuralları hangi sınıf için belirleniyorsa tip parametresi olarak bu sınıf kullanılıyor. Eşleme sınınıfının yapılandırıcısı içinde ise lambda ifadeleri ile sınıfın özelliklerinin ilişkisel veritabanı karşılığının ne olacağı gösteriliyor.

Id(x => x.Id);

ifadesi ile, Store sınıfının Id özelliğinin veritabanında kimlik (identity) kolon olarak oluşturulacağı belirleniyor.

Map(x => x.Name);

ifadesi ile, Store sınıfının Name özelliğinin veritabanında da varsayılan özellikleri ile karşılığı olması gerektiği gösteriliyor.

HasManyToMany(x => x.Products).Cascade.All().Table("StoreProduct");

ile, Store ve Product arasındaki çoka-çok ilişki gösterilmiş oluyor. Mağazaya bağlı ürünlerin, Store nesnesi içindeki Products listesinde saklanacağı anlaşılıyor. Cascade.All() ile de, Store üzerinde yapılan değişikliklerden (Id güncelleme ya da Store nesnesini silme), Store nesnesine bağlı olan Product nesnelerinin de etkileneceği (güncelleme ya da bağlı ürünlerin tamamının otomatik olarak silinmesi) kurala bağlanıyor. Çoka-çok ilişkilerde birbiriyle ilişkili olan kayıtların depolanması için bir üçüncü tabloya ihtiyaç var. İfadenin en sonundaki Table() metodu ile bu tablonun adının ne olacağı belirtiliyor. HasManyToMany metodunun ilişkinin diğer tarafındaki Product nesnesinde de karşılığı olması gerekli. ProductMap içindeki ifade de şu şekilde;

HasManyToMany(x => x.StoresStockedIn).Cascade.All().Inverse().Table("StoreProduct");

Bir ürünün ilişkili olduğu mağazalar, Product içindeki StoresStockedIn listesi ile tutuluyor. Tanımın bu tarafındaki tek fark Inverse() metodu. Bu metod ilişkinin hangi tarafının ilişkinin sahibi olacağını gösteren bir metod. Bu örnekte, ilişkinin depolanması sırasında ilişkinin sahibi Store tarafı. Bu durumda NHibernate Store nesnesini depoluyor, depoladığı Store nesnesinin veritabanı tarafından gelen Id değerini kullanarak Store nesnesinin Products listesindeki nesneleri depoluyor. Inverse kullanılmadığı durumda ise NHibernate, tüm Product nesnelerini Store ile ilişkili değilmiş gibi depolar, ardından Store nesnesini depolar ve Store nesnesinin Id değeri ile daha önce depoladığı Product nesnelerini teker teker günceller.

HasMany(x => x.Staff).Cascade.All().Inverse();

Yukarıdaki eşleme direktifi ile, Store ve Employee arasındaki bire-çok ilişki tanımı yapılıyor. Aynı şekilde Employee sınıfında da bunun karşılığını bulmak mümkün:

References(x => x.Store);

Model içinde bulunmayan ancak sıkça kullanılan bir özellik olan enumerasyonların nasıl eşlenebileceğini göstermek amacıyla Product sınıfına Status adında bir özellik ekledim. Enumerasyonun ve Product sınıfının kısmi tanımı şu şekilde:

public class Product
{
  //...

  public virtual InventoryStatus Status { get; set; }

  //...
}

public enum InventoryStatus
{
  OnOrder = 1,
  AvailableForSale = 2,
  InTransit = 3
}
 

Aksini belirtmediğiniz sürece NHibernate, enumerasyonları string karşılıkları ile saklayacaktır. Yani eğer Status kolonu için eşleme kuralımız şu şekilde olsaydı:

Map(x => x.Status);

Product tablosundaki kayıtları şu şekilde görecektik:

image

Ancak Status için eşlemeyi;

Map(x => x.Status).CustomType<int>();

şeklinde yaparak enumerasyon değerlerini, her bir değerin karşılığı olan int ile depolamış oluyoruz:

image

Product tablosunda gördüğünüz Aisle ve Shelf kolonlarının Product nesnesinden değil, Product ile ilişkili olan Location nesnesinden geldiğini söylemiştik. Fluent ile bu ilişkilendirmeyi sağlayan ProductMap içindeki lambda ifadesi ise şu şekilde:

Component(x => x.Location);

Bu ifadeyle, Product sınıfı içindeki Location özelliğine bağlı olan özelliklerin Product nesnesine aitmiş gibi Product ile aynı tabloda saklanması sağlanmış oluyor. Ancak Product tablosundaki Aisle ve Shelf özelliklerine C# ile erişmek istendiğinde Product.Location.Aisle ve Product.Location.Shelf şeklinde erişilebiliyor (Location özelliğinin null değerine sahip olmadığını varsayıyoruz tabi).

Uygulamanın Çalıştırılması

NHibernate, veritabanı ile tüm iletişimi Session nesneleri üzerinden gerçekleştirir. Bağlantıların yönetimi, bağlantı havuzu yönetimi vs. tamamı Session tarafından bizleri rahatsız etmeyecek şekilde arka planda gerçekleştirilir. Dolayısıyla, veritabanına ulaşmak için öncelikle yapılması gereken, Session konfigürasyonunu gerçekleştirmek. NHibernate soyut fabrika desenini (abstract factory pattern) uygulamaktadır. Bu da demek oluyor ki aslında konfigürasyon yapılması gereken nokta Session örnekleri değil, Session üretiminden sorumlu olan Session fabrikasıdır.

private static ISessionFactory CreateSessionFactory()
{
  return Fluently.Configure()
    .Database(MsSqlConfiguration.MsSql2008<
    .ConnectionString("Server=.\\SQLEXPRESS;Database=FNHSample;Integrated Security=SSPI;"))
    .Mappings(m =>m.FluentMappings.AddFromAssemblyOf<Program>())
    .ExposeConfiguration(cfg => new SchemaExport(cfg).Create(false, true))
    .BuildSessionFactory();
}

Gördüğünüz üzere, tek bir ifade ile hem Nhibernate yapılandırılıyor hem de bir ISessionFactory örneği döndürülüyor. Database() metodunun parametrelerini SQL Server ile çalışacak şekilde değiştirdim. Database() metodunun hemen ardından gelen Mappings() metodu, ClassMap tanımlarının nereden alınacağını gösteriyor. Bu durumda Store sınıfının bulunduğu assembly içinden eşleme tanımlarının okunması sağlanıyor.

ExposeConfiguration ile, SchemaExport nesnesi kullanılarak veritabanı şemasının hemen üstte belirtilen eşleme kuralları dahilinde üretilmesi sağlanıyor. SchemaExport.Create metodunun ilk parametresi, arka planda çalışacak Sql ifadelerinin script olarak üretilmesini kontrol ediyor. İkinci parametre ise şema üretiminin veritabanı üzerinde gerçekleştirilmesini kontrol ediyor. Yani bir başka deyişle, yukarıdaki şekilde kullanıldığında, SQL Server üzerinde model sınıfları için tabloları oluşturmamıza gerek kalmıyor. NHibernate veritabanı içinde ihtiyaç olan tüm tabloları, tablolar içindeki ilişkisel bütünlük kurallarını kendisi tanımlıyor. Zaten farketmiş olduğunuz gibi, modellemeye veritabanından başlamadık. İşin aslı, veritabanı ile hiç ilgilenmedik bile. Modelleri tasarladıktan sonra kalan herşeyi NHibernate zaten hallediyor.

Session fabrikası yapılandırması tamamlandığına göre, fabrika Session üretmeye başlayabilir, biz de böylece nesnelerimizi veritabanında depolamaya başlayabiliriz:

var sessionFactory = CreateSessionFactory();
var session = sessionFactory.OpenSession();

Veritabanında saklanmak üzere bir kaç model örneği:

var barginBasin = new Store { Name = "Bargin Basin" };
var superMart = new Store { Name = "SuperMart" };
var potatoes = new Product { Name = "Potatoes", Price = 3.60, Status = InventoryStatus.AvailableForSale };
var fish = new Product { Name = "Fish", Price = 4.49, Status = InventoryStatus.AvailableForSale, Location = new Location { Aisle = 10, Shelf = 20 } };
var daisy = new Employee { FirstName = "Daisy", LastName = "Harrison" };
var jack = new Employee { FirstName = "Jack", LastName = "Torrance" };
 

Örnekler tanımlandıktan sonra Store, Product ve Employee arasında tanımlanan ilişkilerin veritabanı tarafında kalıcı olması için her sınıf içinde tanımlanmış olan IList koleksiyonları ile nesneler birbirlerine bağlanıyor:

barginBasin.AddProduct(potatoes); barginBasin.AddProduct(fish);
superMart.AddEmployee(daisy);
superMart.AddEmployee(jack);
 

Burada, Store sınıfı içinde tanımlanmış olan AddProduct ve AddEmployee metodları ile ilgili söylenmesi gereken birkaç şey var. Metodların tanımlarına bir bakalım:

public virtual void AddProduct(Product product)
{
  product.StoresStockedIn.Add(this);
  Products.Add(product);
}

public virtual void AddEmployee(Employee employee)
{
  employee.Store = this;
  Staff.Add(employee);
}
 

AddProduct metodu bir Product örneği alıyor ve Product nesnesinin StoresStockedIn listesine Store nesnesinin kendisini ekliyor. Ardından Product nesnesini de Store'un Products listesine atıyor. Böylece çift taraflı olarak aradaki ilişki sağlanmış oluyor. Aynı şey AddEmployee metodu için de geçerli. Ancak burada ilişki bire-çok olduğundan Employee'nin Store özelliğine değer atanıyor ve Employee nesnesi Store'un Staff listesine ekleniyor.

session.SaveOrUpdate(barginBasin);
session.SaveOrUpdate(superMart);

Bu iki satır ifade ile tüm nesne hiyerarşisi bütün ilişkileri ile birlikte veritabanında depolanmış oluyor. Ayrı ayrı her ürünü (Product) ve çalışanı (Employee) veritabanında saklamadığımızı fark etmişsinizdir. Store nesnelerini depolamak, Store nesneleri ile ilişkili olan diğer tüm nesnelerin de veritabanında depolanması için yeterli.

Son olarak, bütün bu bilginin depolandığını teyid etmek için bir Session üzerinden Linq kullanarak veritabanını sorgulayalım. NHibernate üzerinden Linq ile sorgulama yapmak için NHibernate.Linq kütüphanesini indirmeniz gerekiyor. Yazının sonunda bu adresi paylaştım.

session.Linq<Store>().ToList().ForEach(store => WriteStorePretty(store));

Herhangi bir Session örneği üzerinden yukarıdaki sorguyu çalıştırabilirsiniz. NHibernate.Linq ve System.Linq isim uzaylarını tanımlamayı unutmayın. WriteStorePretty metodu örnek proje içinde tanımlanmış bir metod ve Store bilgilerini düzgün bir şekilde ekrana basıyor. Ben de tanımlanmış olan bu metodu kullandım.

Hem OR/M konusunda hem de NHibernate'in Fluent ile kullanımına dair kısa bir giriş yapmaya çalıştım. Umarım faydası olmuştur. Görüşmek üzere!

NHibernate ve NHibernate.Linq: http://sourceforge.net/projects/nhibernate/files/

Fluent NHibernate: http://fluentnhibernate.org/downloads

Fluent NHibernate kaynak kodları: http://github.com/jagregory/fluent-nhibernate

Makale:
NHibernate Genel Önsel Akın
  • Yazılan Yorumlar
  • Yorum Yaz
EYL
28
2019
EYL
28
2019
4916613944329494
EYL
28
2019
EYL
28
2019
4916613944329494
EYL
28
2019
EYL
28
2019
4916613944329494
EYL
28
2019
EYL
28
2019
EYL
28
2019
4916613944329494
EYL
28
2019
EYL
28
2019
EYL
28
2019
4916613944329494
EYL
28
2019
EYL
28
2019
EYL
28
2019
Sayfalar : 1 2 
Yorum yazabilmek için üye girişi yapmalısınız. Üye girişi için tıklayın.
Üye değilseniz Üyel Ol linkine tıklayarak üyeliğinizi hemen başlatabilirisniz.
 
  • Bu Konuda Son 10
  • Eklenen Son 10
  • Bu Konuda Geçmiş 10
Bu Konuda Yazılmış Yazılmış 10 Makale Yükleniyor
Son Eklenen 10 Makale Yükleniyor
Bu Konuda Yazılmış Geçmiş Makaleler Yükleniyor