2013-02-22 21 views
21

Şu anki projemde NHibernate (SQLite kullanarak) ile başladım ve çoğunlukla Linq'de db sorgularını bildiğim için çoğunlukla Query<> kullanıyorum. Biraz daha karmaşık sorgu ile karşı karşıya kalmıştırNHibernate Query <> vs QueryOver <> arasındaki fark nedir?

, ben QueryOver<> biraz araştırma yaptım ve "QueryOver sözdizimi NH özeldir zira" Query<> üzerinden tercih edilmesi gerektiğini düşündüm. Ayrıca, Query<>'un QueryOver<>'un bunu yapamayacağı bir şey yok gibi görünüyor.

Query<>'un tüm kullanımlarını buna göre değiştirmeye başladım. İlk "sorunu" olana kadar uzun değildi, Query<> kullanımı sadece daha kullanışlı görünüyordu. Örnek (tablodaki BillingDataEntity sütun CustomNumber en yüksek değeri seçin): Ne sevmediğim ihtiyaçtır

int result = Session.Query<BillingDataEntity>().Select(x => x.CustomNumber).OrderByDescending(a => a).FirstOrDefault(); 
int result = Session.QueryOver<BillingDataEntity>().Select(x => x.CustomNumber).OrderBy(a => a.CustomNumber).Desc.Take(1).SingleOrDefault<int>(); 

açıkça int sonucu döküm ve Sorgu <> sürüm okumak daha kolay olduğunu söyledi. Sorguyu tamamen yanlış mı, yoksa başka bir deyişle: Bunu yapmanın daha iyi bir yolu var mı?

ben oluşturulan SQL çıkışında bir göz attım:

NHibernate: select billingdat0_.CustomNumber as col_0_0_ from "BillingDataEntity" billingdat0_ order by billingdat0_.CustomNumber desc limit 1 
NHibernate: SELECT this_.CustomNumber as y0_ FROM "BillingDataEntity" this_ ORDER BY this_.CustomNumber desc limit @p0;@p0 = 1 [Type: Int32 (0)] 
tam ben bakıyorum ne

? Bu, NHibernate'in gerçek veritabanı sorgusuna dönüştüğü "iç" (yöntem bağımlı) sorgusudur?

cevap

26

Stackoverflow üzerinde ama kısaca burada Query karşı QueryOver ilgili cevaplar bol vardır: -

QueryOver Kriterleri özellikle yazılan versiyonu ve daha NHibernate özeldir. ICriteria'da yapabileceğiniz hemen hemen her şey QueryOver ile yapılabilir. ICriteria NH2'nin altın günlerinde, her zaman dökümünü yaptınız, bu yüzden şimdi zincirinin sonunda bir int'ye dönmeniz gerekiyor.

LINQ (Sorgu) NHibernate açık referanslar gerek yoktur ve daha ORM agnostik olarak kabul edilir ve bu nedenle linq standardını izler edilebileceği IQueryable çalışan bir standart sorgu yöntemidir. 'un doğru bir şekilde belirttiğiniz gibi, sonuca customNumber seçerek 'u seçtiniz.

Üretilen SQL çok farklıysa basit örnek için çok şaşırdım.

Ben QueryOver büyük bir hayranıyım ama Linq sağlayıcı sonra benim sorguları% 95'ini daha olgun oluyor gibi ben Query kullanmak ancak bazı Nhibernate belirli şeyler için geri QueryOver aşağı başvurmak. Her iki şekilde de yaşayabileceğiniz şeyleri görmek için bir profil aracı kullanmanızı tavsiye ederim.

Refs: Tradeoffs veya versus ve versus sizin QueryOver sürümü hakkında

+0

QueryOver'ın ICiteria'ya dayalı olduğunu ve 'doğru şekilde yaptığınız gibi yapmanın yolu budur' cevabı verdiğim için doğrudan ilk soruma cevap verebileceğinden emin değilim. Oluşturulan SQL'i görmek için orada en iyisi olduğu gibi NHProf gibi bir ticari araç kullanacağım. Künt olmak anlamına gelmez ve HTH verdiğim cevabı açıklığa kavuşturur. – Rippo

+0

Teşekkürler, bazı yararlı bilgiler için + 1'leyin. –

+1

Ayrıca, "Sorgu ", "IEnumerable" IS olan bir "IQueryable" değerini döndürür, bu yüzden süper uygundur. – Jess

3

, yazdım olacaktır:

int result = Session.QueryOver<BillingDataEntity>() 
       .Select(Projections.Max<BillingDataEntity>(x => x.CustomNumber)) 
       .SingleOrDefault<int>(); 

Oldukça okunabilir görünüyor ve ortaya çıkan SQL olurdu gibi bir şey:

SELECT max(this_.CustomNumber) as y0_ FROM "BillingDataEntity" this_ 

Yardım bu yardımcı olur

İlgili konular