@@ -36,7 +36,8 @@ public static Expression<Func<T, bool>> ToFilterExpression<T>(
3636 this FilterQueryOption filterOption ,
3737 HandleNullPropagationOption handleNullPropagation = HandleNullPropagationOption . Default ,
3838 TimeZoneInfo timeZone = null ,
39- bool enableConstantParameterization = true )
39+ bool enableConstantParameterization = true ,
40+ bool ensureStableOrdering = true )
4041 {
4142 if ( filterOption == null )
4243 return null ;
@@ -45,7 +46,7 @@ public static Expression<Func<T, bool>> ToFilterExpression<T>(
4546
4647 queryable = filterOption . ApplyTo (
4748 queryable ,
48- new ODataQuerySettings ( ) { HandleNullPropagation = handleNullPropagation , TimeZone = timeZone , EnableConstantParameterization = enableConstantParameterization } ) ;
49+ new ODataQuerySettings ( ) { HandleNullPropagation = handleNullPropagation , TimeZone = timeZone , EnableConstantParameterization = enableConstantParameterization , EnsureStableOrdering = ensureStableOrdering } ) ;
4950
5051 MethodCallExpression whereMethodCallExpression = ( MethodCallExpression ) queryable . Expression ;
5152
@@ -62,15 +63,16 @@ public static Expression<Func<T, bool>> ToSearchExpression<T>(
6263 this SearchQueryOption filterOption ,
6364 HandleNullPropagationOption handleNullPropagation = HandleNullPropagationOption . Default ,
6465 TimeZoneInfo timeZone = null ,
65- bool enableConstantParameterization = true )
66+ bool enableConstantParameterization = true ,
67+ bool ensureStableOrdering = true )
6668 {
6769 if ( filterOption == null )
6870 return null ;
6971
7072 IQueryable queryable = Enumerable . Empty < T > ( ) . AsQueryable ( ) ;
7173 queryable = filterOption . ApplyTo (
7274 queryable ,
73- new ODataQuerySettings ( ) { HandleNullPropagation = handleNullPropagation , TimeZone = timeZone , EnableConstantParameterization = enableConstantParameterization } ) ;
75+ new ODataQuerySettings ( ) { HandleNullPropagation = handleNullPropagation , TimeZone = timeZone , EnableConstantParameterization = enableConstantParameterization , EnsureStableOrdering = ensureStableOrdering } ) ;
7476
7577 MethodCallExpression whereMethodCallExpression = ( MethodCallExpression ) queryable . Expression ;
7678
@@ -80,7 +82,8 @@ public static Expression<Func<T, bool>> ToSearchExpression<T>(
8082 public static Expression < Func < T , bool > > ToFilterExpression < T > ( this ODataQueryOptions < T > options ,
8183 HandleNullPropagationOption handleNullPropagation = HandleNullPropagationOption . Default ,
8284 TimeZoneInfo timeZone = null ,
83- bool enableConstantParameterization = true )
85+ bool enableConstantParameterization = true ,
86+ bool ensureStableOrdering = true )
8487 {
8588 if ( options is null || options . Filter is null && options . Search is null )
8689 {
@@ -92,14 +95,14 @@ public static Expression<Func<T, bool>> ToFilterExpression<T>(this ODataQueryOpt
9295 Expression filterExpression = null ;
9396 if ( options . Filter is not null )
9497 {
95- var raw = options . Filter . ToFilterExpression < T > ( handleNullPropagation , timeZone , enableConstantParameterization ) ;
98+ var raw = options . Filter . ToFilterExpression < T > ( handleNullPropagation , timeZone , enableConstantParameterization , ensureStableOrdering ) ;
9699 filterExpression = raw . Body . ReplaceParameter ( raw . Parameters [ 0 ] , parameter ) ;
97100 }
98101
99102 Expression searchExpression = null ;
100103 if ( options . Search is not null )
101104 {
102- var raw = options . Search . ToSearchExpression < T > ( handleNullPropagation , timeZone , enableConstantParameterization ) ;
105+ var raw = options . Search . ToSearchExpression < T > ( handleNullPropagation , timeZone , enableConstantParameterization , ensureStableOrdering ) ;
103106 searchExpression = raw . Body . ReplaceParameter ( raw . Parameters [ 0 ] , parameter ) ;
104107 }
105108
@@ -189,6 +192,9 @@ public static Expression GetQueryableMethod(this Expression expression,
189192 if ( orderByClause is null && skip is null && top is null )
190193 return null ;
191194
195+ if ( orderByClause is null && ! oDataSettings . EnsureStableOrdering )
196+ return expression . GetSkipCall ( skip ) . GetTakeCall ( top ) ;
197+
192198 if ( orderByClause is null && ( skip is not null || top is not null ) )
193199 {
194200 var orderBySettings = context . FindSortableProperties ( type ) ;
0 commit comments