The high level problem I am trying to solve is de-duplicated paging when searching for things that may exist in child collections.
The approach I'm taking is by creating a distinct Projection, containing the information pertinent to my DTO. I also know these values don't change between each row.
criteria.SetProjection(
Projections.Distinct(Projections.ProjectionList()
.Add(Projections.Alias(Projections.Property("Id"), "Id"))
.Add(Projections.Alias(Projections.Property("Title"), "Title"))
.Add(Projections.Alias(Projections.Property("Firstname"), "Firstname"))
.Add(Projections.Alias(Projections.Property("Surname"), "Surname"))
.Add(Projections.Alias(Projections.Property("DateCreated"), "DateCreated"))));
The problem occurs when I introduce the paging / ordering elements.
Looking at NH Profiler, I'm seeing the SQL like:-
SELECT TOP (20 /* @p0 */) y0_,
y1_,
y2_,
y3_,
y4_
FROM
(
SELECT distinct
this_.Id as y0_,
this_.Title as y1_,
this_.Firstname as y2_,
this_.Surname as y3_,
this_.DateCreated as y4_,
ROW_NUMBER()
OVER(ORDER BY this_.Firstname DESC, this_.Surname DESC)
as __hibernate_sort_row
FROM Users this_
) as query
WHERE query.__hibernate_sort_row > 20 /* @p1 */
ORDER BY query.__hibernate_sort_row;
My intention, to get a DISTINCT projection, is being thwarted because ROW_NUMBER() is making every row unique.
I have come across this blog post, which describes the same problem I am experiencing.
The solution offered up there involved changing the nHibernate MS SQL code; which is an option, but one I am keen to avoid. Are there options in more recent versions of nHibernate which get around this problem?
EDIT
Fixed in nHibernate 3.3.1 - see answer below.