Skip to content

Commit

Permalink
Merge pull request #3 from johelvisguzman/feature/query-options
Browse files Browse the repository at this point in the history
Introduced sorting and paging options for queries
  • Loading branch information
johelvisguzman authored Mar 7, 2018
2 parents 0426001 + f1c4639 commit 5a2df50
Show file tree
Hide file tree
Showing 8 changed files with 702 additions and 33 deletions.
18 changes: 18 additions & 0 deletions src/DotNetToolkit.Repository/Queries/IQueryOptions.cs
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);
}
}
113 changes: 113 additions & 0 deletions src/DotNetToolkit.Repository/Queries/PagingOptions.cs
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
}
}
69 changes: 69 additions & 0 deletions src/DotNetToolkit.Repository/Queries/SortingOptions.cs
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
}
}
Loading

0 comments on commit 5a2df50

Please sign in to comment.