/// <summary> /// Paginates using keyset pagination. /// </summary> /// <typeparam name="T">The type of the elements of source.</typeparam> /// <param name="source">An <see cref="IQueryable{T}"/> to paginate.</param> /// <param name="builderAction">An action that takes a builder and registers the columns upon which keyset pagination will work.</param> /// <param name="direction">The direction to take. Default is Forward.</param> /// <param name="reference">The reference object. Needs to have properties with exact names matching the configured properties. Doesn't necessarily need to be the same type as T.</param> /// <returns>The modified the queryable.</returns> /// <exception cref="ArgumentNullException">source or builderAction is null.</exception> /// <exception cref="InvalidOperationException">If no properties were registered with the builder.</exception> /// <remarks> /// Note that calling this method will override any OrderBy calls you have done before. /// </remarks> public static IQueryable <T> KeysetPaginateQuery <T>( this IQueryable <T> source, Action <KeysetPaginationBuilder <T> > builderAction, KeysetPaginationDirection direction = KeysetPaginationDirection.Forward, object?reference = null) where T : class { return(KeysetPaginate(source, builderAction, direction, reference).Query); }
internal KeysetPaginationContext( IQueryable <T> query, IOrderedQueryable <T> orderedQuery, IReadOnlyList <KeysetPaginationItem <T> > items, KeysetPaginationDirection direction) { Query = query; OrderedQuery = orderedQuery; Items = items; Direction = direction; }
/// <summary> /// Paginates using keyset pagination. /// </summary> /// <typeparam name="T">The type of the elements of source.</typeparam> /// <param name="source">An <see cref="IQueryable{T}"/> to paginate.</param> /// <param name="builderAction">An action that takes a builder and registers the columns upon which keyset pagination will work.</param> /// <param name="direction">The direction to take. Default is Forward.</param> /// <param name="reference">The reference object. Needs to have properties with exact names matching the configured properties. Doesn't necessarily need to be the same type as T.</param> /// <returns>An object containing the modified queryable. Can be used with other helper methods related to keyset pagination.</returns> /// <exception cref="ArgumentNullException">source or builderAction is null.</exception> /// <exception cref="InvalidOperationException">If no properties were registered with the builder.</exception> /// <remarks> /// Note that calling this method will override any OrderBy calls you have done before. /// </remarks> public static KeysetPaginationContext <T> KeysetPaginate <T>( this IQueryable <T> source, Action <KeysetPaginationBuilder <T> > builderAction, KeysetPaginationDirection direction = KeysetPaginationDirection.Forward, object?reference = null) where T : class { if (source == null) { throw new ArgumentNullException(nameof(source)); } if (builderAction == null) { throw new ArgumentNullException(nameof(builderAction)); } var builder = new KeysetPaginationBuilder <T>(); builderAction(builder); var items = builder.Items; if (!items.Any()) { throw new InvalidOperationException("There should be at least one property you're acting on."); } // Order var orderedQuery = items[0].ApplyOrderBy(source, direction); for (var i = 1; i < items.Count; i++) { orderedQuery = items[i].ApplyThenOrderBy(orderedQuery, direction); } // Filter var filteredQuery = orderedQuery.AsQueryable(); if (reference != null) { var keysetFilterPredicateLambda = BuildKeysetFilterPredicateExpression(items, direction, reference); filteredQuery = filteredQuery.Where(keysetFilterPredicateLambda); } return(new KeysetPaginationContext <T>(filteredQuery, orderedQuery, items, direction)); }
public abstract IOrderedQueryable <T> ApplyThenOrderBy(IOrderedQueryable <T> query, KeysetPaginationDirection direction);