Skip to content

Commit 5a2df50

Browse files
Merge pull request #3 from johelvisguzman/feature/query-options
Introduced sorting and paging options for queries
2 parents 0426001 + f1c4639 commit 5a2df50

File tree

8 files changed

+702
-33
lines changed

8 files changed

+702
-33
lines changed
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
namespace DotNetToolkit.Repository.Queries
2+
{
3+
using System.Linq;
4+
5+
/// <summary>
6+
/// Represents a query options which can be used for sorting or paging on queries.
7+
/// </summary>
8+
/// <typeparam name="T">The entity type of the repository.</typeparam>
9+
public interface IQueryOptions<T>
10+
{
11+
/// <summary>
12+
/// Applies the current options to the specified query.
13+
/// </summary>
14+
/// <param name="query">The query.</param>
15+
/// <returns>The new query with the defined options applied.</returns>
16+
IQueryable<T> Apply(IQueryable<T> query);
17+
}
18+
}
Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
namespace DotNetToolkit.Repository.Queries
2+
{
3+
using System;
4+
using System.Linq;
5+
using System.Linq.Expressions;
6+
7+
/// <summary>
8+
/// Represents a paging option.
9+
/// </summary>
10+
/// <typeparam name="T">The entity type of the repository.</typeparam>
11+
/// <typeparam name="TKey">The type of the property that is being sorted.</typeparam>
12+
public class PagingOptions<T, TKey> : SortingOptions<T, TKey>
13+
{
14+
#region Fields
15+
16+
private const int DefaultPageSize = 100;
17+
private int _pageIndex;
18+
private int _pageSize;
19+
20+
#endregion
21+
22+
#region Properties
23+
24+
/// <summary>
25+
/// Gets or sets the number of rows of the data page to retrieve.
26+
/// </summary>
27+
public int PageSize
28+
{
29+
get { return _pageSize; }
30+
set
31+
{
32+
if (value <= 0)
33+
throw new ArgumentException($"{nameof(PageSize)} cannot be lower than zero.");
34+
35+
_pageSize = value;
36+
}
37+
}
38+
39+
/// <summary>
40+
/// Gets or sets the zero-based index of the data page to retrieve.
41+
/// </summary>
42+
public int PageIndex
43+
{
44+
get { return _pageIndex; }
45+
set
46+
{
47+
if (value < 1)
48+
throw new ArgumentOutOfRangeException(nameof(PageIndex), "Cannot be lower than 1.");
49+
50+
_pageIndex = value;
51+
}
52+
}
53+
54+
/// <summary>
55+
/// Gets the page count.
56+
/// </summary>
57+
public int PageCount { get; private set; }
58+
59+
#endregion
60+
61+
#region Constructors
62+
63+
/// <summary>
64+
/// Initializes a new instance of the <see cref="PagingOptions{TEntity, TKey}"/> class.
65+
/// </summary>
66+
/// <param name="pageIndex">The zero-based index of the data page to retrieve.</param>
67+
/// <param name="sorting">The sorting expression.</param>
68+
/// <param name="isDescending">if set to <c>true</c> use descending order; otherwise, use ascending.</param>
69+
public PagingOptions(int pageIndex, Expression<Func<T, TKey>> sorting, bool isDescending = false) : base(sorting, isDescending)
70+
{
71+
PageIndex = pageIndex;
72+
PageSize = DefaultPageSize;
73+
}
74+
75+
/// <summary>
76+
/// Initializes a new instance of the <see cref="PagingOptions{TEntity, TKey}"/> class.
77+
/// </summary>
78+
/// <param name="pageIndex">The zero-based index of the data page to retrieve.</param>
79+
/// <param name="pageSize">The number of rows of the data page to retrieve.</param>
80+
/// <param name="sorting">The sorting expression.</param>
81+
/// <param name="isDescending">if set to <c>true</c> use descending order; otherwise, use ascending.</param>
82+
public PagingOptions(int pageIndex, int pageSize, Expression<Func<T, TKey>> sorting, bool isDescending = false) : base(sorting, isDescending)
83+
{
84+
PageIndex = pageIndex;
85+
PageSize = pageSize;
86+
}
87+
88+
#endregion
89+
90+
#region Overrides of SortingOptions<TEntity,TKey>
91+
92+
/// <summary>
93+
/// Applies the current options to the specified query.
94+
/// </summary>
95+
/// <param name="query">The query.</param>
96+
/// <returns>The new query with the defined options applied.</returns>
97+
public override IQueryable<T> Apply(IQueryable<T> query)
98+
{
99+
var pageCount = (int)Math.Ceiling(query.Count() / (decimal)PageSize);
100+
101+
if (PageIndex > pageCount)
102+
throw new ArgumentOutOfRangeException(nameof(PageIndex), "Cannot be greater than the total number of pages.");
103+
104+
PageCount = pageCount;
105+
106+
query = base.Apply(query);
107+
108+
return query.Skip((PageIndex - 1) * PageSize).Take(PageSize);
109+
}
110+
111+
#endregion
112+
}
113+
}
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
namespace DotNetToolkit.Repository.Queries
2+
{
3+
using System;
4+
using System.Linq;
5+
using System.Linq.Expressions;
6+
7+
/// <summary>
8+
/// Represents a sorting option.
9+
/// </summary>
10+
/// <typeparam name="T">The entity type of the repository.</typeparam>
11+
/// <typeparam name="TKey">The type of the property that is being sorted.</typeparam>
12+
public class SortingOptions<T, TKey> : IQueryOptions<T>
13+
{
14+
#region Fields
15+
16+
private readonly Expression<Func<T, TKey>> _sorting;
17+
18+
#endregion
19+
20+
#region Properties
21+
22+
/// <summary>
23+
/// Gets or sets a value indicating whether this sorting option is descending.
24+
/// </summary>
25+
/// <value>
26+
/// <c>true</c> if this sorting option is descending; otherwise, <c>false</c>.
27+
/// </value>
28+
public bool IsDescending { get; set; }
29+
30+
#endregion
31+
32+
#region Constructors
33+
34+
/// <summary>
35+
/// Initializes a new instance of the <see cref="SortingOptions{TEntity, TKey}"/> class.
36+
/// </summary>
37+
/// <param name="sorting">The sorting expression.</param>
38+
/// <param name="isDescending">if set to <c>true</c> use descending order; otherwise, use ascending.</param>
39+
public SortingOptions(Expression<Func<T, TKey>> sorting, bool isDescending = false)
40+
{
41+
_sorting = sorting;
42+
43+
IsDescending = isDescending;
44+
}
45+
46+
#endregion
47+
48+
#region Implementation of IQueryOptions<T>
49+
50+
/// <summary>
51+
/// Applies the current options to the specified query.
52+
/// </summary>
53+
/// <param name="query">The query.</param>
54+
/// <returns>The new query with the defined options applied.</returns>
55+
public virtual IQueryable<T> Apply(IQueryable<T> query)
56+
{
57+
if (_sorting != null)
58+
{
59+
query = IsDescending
60+
? query.OrderByDescending(_sorting)
61+
: query.OrderBy(_sorting);
62+
}
63+
64+
return query;
65+
}
66+
67+
#endregion
68+
}
69+
}

0 commit comments

Comments
 (0)