@@ -254,7 +254,7 @@ private static Expression<Func<T, bool>> BuildKeysetFilterPredicateExpression<T>
254254 var referenceValues = GetValues ( items , reference ) ;
255255
256256 var firstMemberAccessExpression = default ( MemberExpression ) ;
257- var firstReferenceValueExpression = default ( ConstantExpression ) ;
257+ var firstReferenceValueExpression = default ( Expression ) ;
258258
259259 // entity =>
260260 var param = Expression . Parameter ( typeof ( T ) , "entity" ) ;
@@ -273,7 +273,9 @@ private static Expression<Func<T, bool>> BuildKeysetFilterPredicateExpression<T>
273273 var isInnerLastOperation = j + 1 == innerLimit ;
274274 var item = items [ j ] ;
275275 var memberAccess = Expression . MakeMemberAccess ( param , item . Property ) ;
276- var referenceValueExpression = Expression . Constant ( referenceValues [ j ] ) ;
276+ var referenceValue = referenceValues [ j ] ;
277+ Expression < Func < object > > referenceValueFunc = ( ) => referenceValue ;
278+ var referenceValueExpression = referenceValueFunc . Body ;
277279
278280 if ( firstMemberAccessExpression == null )
279281 {
@@ -330,7 +332,7 @@ private static Expression<Func<T, bool>> BuildKeysetFilterPredicateExpression<T>
330332
331333 private static BinaryExpression MakeComparisonExpression < T > (
332334 KeysetPaginationItem < T > item ,
333- MemberExpression memberAccess , ConstantExpression referenceValue ,
335+ MemberExpression memberAccess , Expression referenceValue ,
334336 Func < Expression , Expression , BinaryExpression > compare )
335337 where T : class
336338 {
@@ -340,11 +342,14 @@ private static BinaryExpression MakeComparisonExpression<T>(
340342 // LessThan/GreaterThan operators are not valid for some types such as strings and guids.
341343 // We use the CompareTo method on these types instead.
342344
343- // entity.Property.CompareTo(constant ) >|< 0
345+ // entity.Property.CompareTo(referenceValue ) >|< 0
344346 // -----------------------------------------
345347
346- // entity.Property.CompareTo(constant)
347- var methodCallExpression = Expression . Call ( memberAccess , compareToMethod , referenceValue ) ;
348+ // entity.Property.CompareTo(referenceValue)
349+ var methodCallExpression = Expression . Call (
350+ memberAccess ,
351+ compareToMethod ,
352+ EnsureMatchingType ( memberAccess , referenceValue ) ) ;
348353
349354 // >|< 0
350355 return compare ( methodCallExpression , ConstantExpression0 ) ;
@@ -361,21 +366,18 @@ private static Expression EnsureMatchingType(
361366 MemberExpression memberExpression ,
362367 Expression targetExpression )
363368 {
364- // If the member is nullable we'll have to make sure the target type matches or else comparison/equal
365- // expressions won't work because of unmatching types.
366- if ( IsNullableType ( memberExpression . Type ) && memberExpression . Type != targetExpression . Type )
369+ // If the target has a different type we should convert it.
370+ // Originally this happened with nullables only, but now that we use expressions
371+ // for the target access instead of constants we'll need this or else comparison won't work
372+ // between unmatching types (i.e int (member) compared to object (target)).
373+ if ( memberExpression . Type != targetExpression . Type )
367374 {
368375 return Expression . Convert ( targetExpression , memberExpression . Type ) ;
369376 }
370377
371378 return targetExpression ;
372379 }
373380
374- private static bool IsNullableType ( Type type )
375- {
376- return type . IsGenericType && type . GetGenericTypeDefinition ( ) == typeof ( Nullable < > ) ;
377- }
378-
379381 private static Func < Expression , Expression , BinaryExpression > GetComparisonExpressionToApply < T > (
380382 KeysetPaginationDirection direction , KeysetPaginationItem < T > item , bool orEqual )
381383 where T : class
0 commit comments