public IList List(ISessionImplementor session, QueryParameters queryParameters) { // Delegate to the QueryLoader... ErrorIfDML(); var query = ( QueryNode ) _sqlAst; bool hasLimit = queryParameters.RowSelection != null && queryParameters.RowSelection.DefinesLimits; bool needsDistincting = ( query.GetSelectClause().IsDistinct || hasLimit ) && ContainsCollectionFetches; QueryParameters queryParametersToUse; if ( hasLimit && ContainsCollectionFetches ) { log.Warn( "firstResult/maxResults specified with collection fetch; applying in memory!" ); var selection = new RowSelection { FetchSize = queryParameters.RowSelection.FetchSize, Timeout = queryParameters.RowSelection.Timeout }; queryParametersToUse = queryParameters.CreateCopyUsing( selection ); } else { queryParametersToUse = queryParameters; } IList results = _queryLoader.List(session, queryParametersToUse); if ( needsDistincting ) { int includedCount = -1; // NOTE : firstRow is zero-based int first = !hasLimit || queryParameters.RowSelection.FirstRow == RowSelection.NoValue ? 0 : queryParameters.RowSelection.FirstRow; int max = !hasLimit || queryParameters.RowSelection.MaxRows == RowSelection.NoValue ? -1 : queryParameters.RowSelection.MaxRows; int size = results.Count; var tmp = new List<object>(); var distinction = new IdentitySet(); for ( int i = 0; i < size; i++ ) { object result = results[i]; if ( !distinction.Add(result ) ) { continue; } includedCount++; if ( includedCount < first ) { continue; } tmp.Add( result ); // NOTE : ( max - 1 ) because first is zero-based while max is not... if ( max >= 0 && ( includedCount - first ) >= ( max - 1 ) ) { break; } } results = tmp; } return results; }