-
Notifications
You must be signed in to change notification settings - Fork 5
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #3 from johelvisguzman/feature/query-options
Introduced sorting and paging options for queries
- Loading branch information
Showing
8 changed files
with
702 additions
and
33 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,18 @@ | ||
namespace DotNetToolkit.Repository.Queries | ||
{ | ||
using System.Linq; | ||
|
||
/// <summary> | ||
/// Represents a query options which can be used for sorting or paging on queries. | ||
/// </summary> | ||
/// <typeparam name="T">The entity type of the repository.</typeparam> | ||
public interface IQueryOptions<T> | ||
{ | ||
/// <summary> | ||
/// Applies the current options to the specified query. | ||
/// </summary> | ||
/// <param name="query">The query.</param> | ||
/// <returns>The new query with the defined options applied.</returns> | ||
IQueryable<T> Apply(IQueryable<T> query); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,113 @@ | ||
namespace DotNetToolkit.Repository.Queries | ||
{ | ||
using System; | ||
using System.Linq; | ||
using System.Linq.Expressions; | ||
|
||
/// <summary> | ||
/// Represents a paging option. | ||
/// </summary> | ||
/// <typeparam name="T">The entity type of the repository.</typeparam> | ||
/// <typeparam name="TKey">The type of the property that is being sorted.</typeparam> | ||
public class PagingOptions<T, TKey> : SortingOptions<T, TKey> | ||
{ | ||
#region Fields | ||
|
||
private const int DefaultPageSize = 100; | ||
private int _pageIndex; | ||
private int _pageSize; | ||
|
||
#endregion | ||
|
||
#region Properties | ||
|
||
/// <summary> | ||
/// Gets or sets the number of rows of the data page to retrieve. | ||
/// </summary> | ||
public int PageSize | ||
{ | ||
get { return _pageSize; } | ||
set | ||
{ | ||
if (value <= 0) | ||
throw new ArgumentException($"{nameof(PageSize)} cannot be lower than zero."); | ||
|
||
_pageSize = value; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets or sets the zero-based index of the data page to retrieve. | ||
/// </summary> | ||
public int PageIndex | ||
{ | ||
get { return _pageIndex; } | ||
set | ||
{ | ||
if (value < 1) | ||
throw new ArgumentOutOfRangeException(nameof(PageIndex), "Cannot be lower than 1."); | ||
|
||
_pageIndex = value; | ||
} | ||
} | ||
|
||
/// <summary> | ||
/// Gets the page count. | ||
/// </summary> | ||
public int PageCount { get; private set; } | ||
|
||
#endregion | ||
|
||
#region Constructors | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PagingOptions{TEntity, TKey}"/> class. | ||
/// </summary> | ||
/// <param name="pageIndex">The zero-based index of the data page to retrieve.</param> | ||
/// <param name="sorting">The sorting expression.</param> | ||
/// <param name="isDescending">if set to <c>true</c> use descending order; otherwise, use ascending.</param> | ||
public PagingOptions(int pageIndex, Expression<Func<T, TKey>> sorting, bool isDescending = false) : base(sorting, isDescending) | ||
{ | ||
PageIndex = pageIndex; | ||
PageSize = DefaultPageSize; | ||
} | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="PagingOptions{TEntity, TKey}"/> class. | ||
/// </summary> | ||
/// <param name="pageIndex">The zero-based index of the data page to retrieve.</param> | ||
/// <param name="pageSize">The number of rows of the data page to retrieve.</param> | ||
/// <param name="sorting">The sorting expression.</param> | ||
/// <param name="isDescending">if set to <c>true</c> use descending order; otherwise, use ascending.</param> | ||
public PagingOptions(int pageIndex, int pageSize, Expression<Func<T, TKey>> sorting, bool isDescending = false) : base(sorting, isDescending) | ||
{ | ||
PageIndex = pageIndex; | ||
PageSize = pageSize; | ||
} | ||
|
||
#endregion | ||
|
||
#region Overrides of SortingOptions<TEntity,TKey> | ||
|
||
/// <summary> | ||
/// Applies the current options to the specified query. | ||
/// </summary> | ||
/// <param name="query">The query.</param> | ||
/// <returns>The new query with the defined options applied.</returns> | ||
public override IQueryable<T> Apply(IQueryable<T> query) | ||
{ | ||
var pageCount = (int)Math.Ceiling(query.Count() / (decimal)PageSize); | ||
|
||
if (PageIndex > pageCount) | ||
throw new ArgumentOutOfRangeException(nameof(PageIndex), "Cannot be greater than the total number of pages."); | ||
|
||
PageCount = pageCount; | ||
|
||
query = base.Apply(query); | ||
|
||
return query.Skip((PageIndex - 1) * PageSize).Take(PageSize); | ||
} | ||
|
||
#endregion | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
namespace DotNetToolkit.Repository.Queries | ||
{ | ||
using System; | ||
using System.Linq; | ||
using System.Linq.Expressions; | ||
|
||
/// <summary> | ||
/// Represents a sorting option. | ||
/// </summary> | ||
/// <typeparam name="T">The entity type of the repository.</typeparam> | ||
/// <typeparam name="TKey">The type of the property that is being sorted.</typeparam> | ||
public class SortingOptions<T, TKey> : IQueryOptions<T> | ||
{ | ||
#region Fields | ||
|
||
private readonly Expression<Func<T, TKey>> _sorting; | ||
|
||
#endregion | ||
|
||
#region Properties | ||
|
||
/// <summary> | ||
/// Gets or sets a value indicating whether this sorting option is descending. | ||
/// </summary> | ||
/// <value> | ||
/// <c>true</c> if this sorting option is descending; otherwise, <c>false</c>. | ||
/// </value> | ||
public bool IsDescending { get; set; } | ||
|
||
#endregion | ||
|
||
#region Constructors | ||
|
||
/// <summary> | ||
/// Initializes a new instance of the <see cref="SortingOptions{TEntity, TKey}"/> class. | ||
/// </summary> | ||
/// <param name="sorting">The sorting expression.</param> | ||
/// <param name="isDescending">if set to <c>true</c> use descending order; otherwise, use ascending.</param> | ||
public SortingOptions(Expression<Func<T, TKey>> sorting, bool isDescending = false) | ||
{ | ||
_sorting = sorting; | ||
|
||
IsDescending = isDescending; | ||
} | ||
|
||
#endregion | ||
|
||
#region Implementation of IQueryOptions<T> | ||
|
||
/// <summary> | ||
/// Applies the current options to the specified query. | ||
/// </summary> | ||
/// <param name="query">The query.</param> | ||
/// <returns>The new query with the defined options applied.</returns> | ||
public virtual IQueryable<T> Apply(IQueryable<T> query) | ||
{ | ||
if (_sorting != null) | ||
{ | ||
query = IsDescending | ||
? query.OrderByDescending(_sorting) | ||
: query.OrderBy(_sorting); | ||
} | ||
|
||
return query; | ||
} | ||
|
||
#endregion | ||
} | ||
} |
Oops, something went wrong.