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?
Belki de yanlış yöne gidiyorsunuz. Yıldız şeması oluşturmaya ve hesaplanan ölçümleri önceden doldurmaya ne dersiniz? – epitka
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. :) –