2011-02-07 23 views
8

Oldukça basit bir veritabanında raporlama yapmak için boyutsal modelleme gibi birkaç veri ambarı ilkesini kullanan bir uygulamam var.SQL İstatistiksel sorgu - bu NHibernate LINQ ile mümkün mü?

bir örneği (basitleştirilmiş) varlık adında Çağrı şuna benzer: onlar alakasız olarak

public virtual long Id { get; set; } 
    public virtual string OriginatorNumber { get; set; } 
    public virtual string DestinationNumber { get; set; } 
    public virtual DateDimension DateDimension { get; set; } 

gerçek modelinin özelliklerinin Birkaç kaldırıldı. basitleştirilmiş DateDimension şuna benzer:

public virtual long Id { get; set; } 
    public virtual DateTime Date { get; set; } 
    public virtual int DayOfMonth { get; set; } 
    public virtual int Weekday { get; set; } 

böyle bir LOT daha sütun bulunmaktadır - bunlar uygulama Kur tarafından geçerli on yıldır önceden doldurulmuş olan. Bu nedenle, tüm on yılın her bir tarihinin bu tabloda bir satırı vardır ve her Arama'nın gerçekleştiği tarihe ait bir bağlantısı vardır. Bu Fluent NHibernate'de haritalanmış ve iyi çalışıyor.

Bazı raporlama yapmak istiyorsanız, bunu 3.0'da geliştirilmiş NHibernate LINQ sağlayıcısıyla kolayca yapabilirim. LINQ'u bize sağladığı gelişmiş bakım için kullanmak isteriz, fakat eğer gerçekten bir zorunluluk olsa da, HQL, ICriteria ve hatta düz SQL'i dikkate alacağız.

Belirli bir numaradan gelen çağrıların sayısını, gerçekleştikleri haftanın günlerine bölünerek gösteren bir rapor oluşturmak istiyorum. Kolayca bu şekilde yapabilir: Bu örnekte

 var query = Calls 
      .Where(c => c.OriginatorNumber == "402") 
      .GroupBy(c => c.DateDimension.Weekday) 
      .Select(g => new { Day = g.Key, Calls = g.Count() }); 

, "Aramalar" bir IQueryable bir depo arayüz üzerinden NHibernates LINQ sağlayıcısına (Sorgu) döndürülen temelde. Yukarıdaki sorgu bana doğru sonuçları veriyor, NHibernate Profiler bana SQL'in oldukça iyi olduğunu gösteriyor, hepsi iyi.

Bununla birlikte, biraz daha gelişmiş bir şey yapmak istiyorsam, takılıyorum. Hafta içi gün başına ortalama arama sayısını istiyorum. Yukarıdakilerden çok uzak değil, değil mi? Sadece hafta içi her gün sonuç kümesindeki benzersiz tarihlerin sayısını bulmalıyım, toplam arama sayısını bölüp, hepimiz ayarladık - doğru mu? Hayır, hayır, burası NHibernate LINQ sağlayıcısının sınırlarını vurmaya başladım. nesnelere LINQ ile bunu yapmak için bir sorgu olustursaydiniz -

.Select(g => g.Count()/g.GroupBy(c => c.DateDimension.Date).Count()); 

çizgisinde bir şey NHibernate bunu kullanırken Ancak bu doğru sorguya dönüştürmez. Bunun yerine, yukarıdaki her iki .Count() çağrısı çağrı kayıtlarının aynı sayısına (*) döner, bu nedenle sonuç her zaman 1'dir.

Elbette her arama, hafta içi gün ve tarih için bir sorgu gibi Yeni anonim nesne, daha sonra uygulama tarafında matematik yapmak, ancak geleneksel bilgelik göre, Bu Sadece Yanlış (tm). Bunu çaresizlik içinde bitirebilirim, hatta, tablonun milyonlarca ++ büyürken acı çekmesi anlamına gelir.

Aşağıda, aradığım sonucu veren bir SQL sorgusu var.

select ss.Weekday, AVG(cast(ss.Count as decimal)) 
from 
(
select dd.Weekday, dd.Date, COUNT(*) as Count 
from Call c 
left outer join DateDimension dd 
    on c.DateDimension_id = dd.Id 
where c.OriginatorNumber = '402' 
group by dd.Weekday, dd.Date 
) ss 
group by ss.Weekday 
order by ss.Weekday 

Bunu NHibernate LINQ sağlayıcısı ile yapmak mümkün müdür? Ya da, eğer bu mümkün değilse, uygulamanın aracı sonucu almasını ve geri kalanını yapmasına izin vermeden önce ne kadar yakınlaşabilirim?

+0

Belki de yanlış yöne gidiyorsunuz. Yıldız şeması oluşturmaya ve hesaplanan ölçümleri önceden doldurmaya ne dersiniz? – epitka

+0

Pekala, bu ilginç bir nokta - ancak benim anlayışım, "olgu" tablosundaki her bir varlığın (örneğin, örneğimde çağrılar) her ilgili boyut tablosuna bir FK'nin sahip olmasıdır. Çağrıların tarihini belirlememde yardımcı olan bir yıldız şemasını nasıl oluşturabilirim? Ama genel olarak, bu konuda yanlış yollara gidiyorum olasılığına çok açıkım. :) –

cevap

1

LINQ sağlayıcısıyla yapamayacağınız pek çok şey var. HQL veya CreateCriteria kullanmak, NHibernate ile kabul etmeniz gereken bir şeydir.

Denemedim, ancak HQL veya CreateCriteria (DetatchedCriteria ile) kullanarak yapmak istediğiniz şeyi yapabilmeniz gerektiği gibi görünüyor.

Çaresiz iseniz, CreateSqlQuery'yi kullanarak düz SQL'e de dönebilirsiniz.

+1

Merhaba, ve cevabınız için teşekkürler. Evet, buna geri dönmek zorunda kalacağım - problem temelde kullanıcılara IQueryable 'u temel alan bir API ile sunmak istedim, böylece gruplama için IQueryable'i iletmeden önce Where() ile bazı filtreleme yapabilirler. Çok zarif olurdu - sanırım gerçekten yapmam gereken, büyük bir kodlayıcı haline geldi ve NHibernate'e katkıda bulundu. :) Girdi için teşekkürler, bir şeyler yapmanın HQL ve ICriteria yollarına bakacağım. –

İlgili konular