상당히 간단한 데이터베이스에 대한보고를 수행하기 위해 차원 모델링과 같은 몇 가지 데이터웨어 하우징 원칙을 사용하는 응용 프로그램이 있습니다.SQL의 통계 쿼리 - NHibernate LINQ로 가능합니까?
예 (간체) 엔티티라는 이름의 전화는 다음과 같습니다 그들이 무관으로
public virtual long Id { get; set; }
public virtual string OriginatorNumber { get; set; }
public virtual string DestinationNumber { get; set; }
public virtual DateDimension DateDimension { get; set; }
실제 모델의 속성 중 일부가 제거되었습니다. 단순화 된 DateDimension은 다음과 같습니다
public virtual long Id { get; set; }
public virtual DateTime Date { get; set; }
public virtual int DayOfMonth { get; set; }
public virtual int Weekday { get; set; }
는 다음과 같이 더 많은 열이 있습니다 - 그들은 응용 프로그램 설치하여 현재 십 년이 미리 채워져 있습니다. 따라서 전체 테이블의 각 날짜에는이 테이블에 행이 있으며 각 호출에는 발생한 날짜에 대한 링크가 있습니다. 이것은 모두 Fluent NHibernate에 매핑되어 있으며 정상적으로 작동합니다.
보고를하고 싶다면 3.0에서 개선 된 NHibernate LINQ 공급자를 사용하면됩니다. 개선 된 유지 보수성을 위해 LINQ를 사용하고 싶습니다만, 실제로해야한다면 HQL, ICriteria 또는 일반 SQL을 고려할 것입니다.
그래서 특정 숫자의 호출 수가 발생한 요일로 나눈 보고서를 작성하려고합니다. 내가 쉽게 이런 식으로 그렇게 할 수 있습니다 :이 예에서는
var query = Calls
.Where(c => c.OriginatorNumber == "402")
.GroupBy(c => c.DateDimension.Weekday)
.Select(g => new { Day = g.Key, Calls = g.Count() });
를 "호출"을 IQueryable이 저장소 인터페이스를 통해 NHibernates LINQ 공급자 (쿼리)에서 반환 된 기본적으로. 위의 쿼리는 저에게 정확한 결과를 제공합니다. NHibernate Profiler는 SQL이 매우 최적이라는 것을 보여 주며 모든 것이 잘됩니다.
그러나 조금 더 진보 된 것을하고 싶다면, 나는 고생한다. 평일 평균 통화 수를 원한다고 가정 해보십시오. 위와 너무 멀지 않은가? 결과 세트에있는 각 요일의 고유 한 날짜 수를 파악하고 총 호출 수를 나누면됩니다. 우리는 모두 설정되어 있습니까? 음, 아니요, 이것이 NHibernate LINQ 공급자의 한계에 부딪히기 시작하는 곳입니다. 개체에 LINQ와 나는 그것을 할 수있는 쿼리를 생성 할 수 -
.Select(g => g.Count()/g.GroupBy(c => c.DateDimension.Date).Count());
의 라인을 따라 뭔가를 NHibernate에 그것을 사용하는 경우 그러나,이 올바른 쿼리로 변환하지 않습니다. 대신 위의 두 .Count() 호출을 호출 레코드의 수 (*)를 동일하게 설정하므로 결과는 항상 1입니다.
물론 각 호출, 평일 및 날짜를 a로 쿼리해야합니다. 새로운 익명 객체, 그런 다음 응용 프로그램 측면에서 수학을 수행하지만, 일반적인 지혜에 따르면, 그건 그냥 틀렸어 (TM). 나는 절망에서 그것을 끝낼 수 있었다, tho, 심지어 tho는 테이블이 100만의 ++ 전화까지 성장할 때 고통을 의미한다.
다음은 내가 찾고있는 결과를 제공하는 SQL 쿼리입니다.
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
그것은 NHibernate에 LINQ 공급자와 함께이 작업을 수행 할 수 있습니까? 또는 이것이 가능하지 않은 경우 응용 프로그램이 중간 결과를 가져와 나머지 작업을 수행하기 전에 얼마나 가까워 야합니까?
어쩌면 당신은 그것에 대해 잘못된 길을 가고 있습니다. 스타 스키마를 만들고 계산 된 측정 값을 미리 채우는 것은 어떻습니까? – epitka
글쎄요, 흥미로운 점입니다. 그러나 "사실"테이블의 각 항목 (예 : 내 사례의 호출)은 각 관련 차원 테이블에 하나의 FK가 있음을 이해합니다. 통화 날짜를 파악하고 각 통화 기록에서 해당 통화를 가리키는 데 도움이되는 별표 스키마를 만들려면 어떻게해야합니까? 그러나 일반적으로 나는 잘못된 방향으로 갈 가능성에 대해 매우 열려 있습니다. :) –