NHibernate Pagination Without Deterministic OrderBy: Inconsistent Result Sets
0 reputation · 09 Jul 2025, 01:24 UTC
NHibernate's LINQ provider translates Skip() and Take() into SQL OFFSET/FETCH or LIMIT/OFFSET depending on the configured dialect. A documented behavioral ambiguity arises when these methods are applied without an explicit OrderBy clause, as the database may return rows in an unspecified order, producing inconsistent page results across separate executions. This uncertainty impacts user-facing workflows that rely on predictable pagination, particularly where data ordering is implicit or dynamically configured. The interaction between dialect-specific SQL generation and the absence of a deterministic sort order creates a gap between expected and actual user experience.
Furthermore, older SQL dialects that lack native OFFSET/FETCH support may cause NHibernate to materialize a larger intermediate result set into memory before applying client-side paging, which can degrade performance and increase resource consumption. Version-specific LINQ provider implementations add variability, as behavior regarding implicit ordering and row materialization has differed across NHibernate releases.
Which NHibernate release first ensured consistent implicit ORDER BY generation for Skip() and Take()? Under what precise conditions does the LINQ provider emit a stable ORDER BY clause when none is authored by the developer? Can keyset pagination be integrated into existing IQueryable pipelines without disrupting current query abstractions or requiring full query rewrites?