I am basically trying to create this query with NHibernate ICriteria interface:
SomeTable 1:n AnotherTable
SomeTable has columns: PrimaryKey, NonAggregateColumn
AnotherTable has columns: 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
It is clear that using Projection subquery is not very efficient, since SQL has to scan the table twice (one projection subquery per aggregate).
Using multiple GROUP BYs is not efficient as well.
Is there a solution for this ? So far I've been resorting to using raw SQL but this is getting unwieldy for complex reports.
Unfortunately, Criteria is a bit restricted.
Try this:
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[]>();
You probably need to play around a bit, it's more of a guess. It also might be impossible this way.
It should produce something like this:
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
Generally:
DetachedCriteria
. See the docs for more details.in
, exists
etc.)AnotherTable
and navigate to SomeTable
. This might be a alternative solution.If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With