我基本上尝试使用NHibernate ICriteria接口创建此查询:
SomeTable 1:n AnotherTable
SomeTable 包含列:PrimaryKey,NonAggregateColumn
AnotherTable 包含以下列:PrimaryKey,ForeignKey,AnotherNonAggregate,YetAnotherNonAggregate
SELECT
table1.NonAggregateColumn,
subquery.SubQueryAggregate1,
subquery.SubQueryAggregate2
FROM
SomeTable AS table1
LEFT JOIN
(
SELECT
table2.ForeignKey,
COUNT(table2.AnotherNonAggregate) AS SubQueryAggregate1,
AVG(table2.YetAnotherNonAggregate) AS SubQueryAggregate2
FROM AnotherTable AS table2
GROUP BY (table2.ForeignKey)
) AS subquery ON subquery.ForeignKey = table1.PrimaryKey
很明显,使用Projection子查询效率不高,因为SQL必须扫描两次表(每个聚合一个投影子查询)。
使用多个GROUP BY也不高效。
有解决方案吗?到目前为止,我一直在使用原始SQL,但这对于复杂的报告来说变得难以处理。
答案 0 :(得分:2)
不幸的是,Criteria有点受限制。
试试这个:
session.CreateCriteria(typeof(SomeTable), "st")
.SetProjection( Projections.ProjectionList()
.Add(Projections.GroupProperty("st.id"))
.Add(Projections.GroupProperty("st.NonAggregateColumn"))
.Add(Projections.RowCount(), "rowcount")
.Add(Projections.Avg("at.YetAnotherNonAggregate"), "avg"));
.CreateCriteria( "st.OtherTables", "at", JoinType.InnerJoin)
.List<object[]>();
你可能需要玩一下,这更像是猜测。这也可能是不可能的。
它应该产生这样的东西:
select
st.id,
st.NonAggregateColumn,
count() as "rowcount",
avg(at.YetAnotherNonAggregate) as "avg"
from
SomeTable st inner join AnotherTable at on ...
group by
st.id,
st.NonAggregateColumn
一般而言:
DetachedCriteria
制作子查询。有关详细信息,请参阅the docs。in
,exists
等。)AnotherTable
开始,然后导航至SomeTable
。这可能是另一种解决方案。