Skip to content

Commit eab97d6

Browse files
authored
Merge pull request #240 from SharpRepository/consolidateOrderBy
Removed duplicated code in Paging and Sorting Options implementations…
2 parents 34c910b + fbe107c commit eab97d6

File tree

4 files changed

+85
-122
lines changed

4 files changed

+85
-122
lines changed

SharpRepository.Repository/Queries/PagingOptions.cs

Lines changed: 10 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -9,53 +9,19 @@ namespace SharpRepository.Repository.Queries
99
/// </summary>
1010
/// <typeparam name="T">The entity type of the repository.</typeparam>
1111
/// <typeparam name="TSortKey">The type of the property that is being sorted.</typeparam>
12-
public class PagingOptions<T, TSortKey> : SortingOptions<T, TSortKey>, IPagingOptions
12+
public class PagingOptions<T, TSortKey> : PagingOptions<T>
1313
{
14-
public int PageSize { get; set; }
15-
public int PageNumber { get; set; }
16-
public int Skip { get { return (PageNumber - 1) * PageSize; } }
17-
public int Take { get { return PageSize; } }
18-
public int TotalItems { get; set; }
19-
2014
public PagingOptions(int pageNumber, int pageSize, Expression<Func<T, TSortKey>> sortExpression, bool isDescending = false)
21-
: base(sortExpression, isDescending)
15+
: base(pageNumber, pageSize, sortExpression.ToString(), isDescending)
2216
{
23-
PageSize = pageSize;
24-
PageNumber = pageNumber;
25-
}
26-
27-
/// <summary>
28-
/// Applies paging to the specified query.
29-
/// </summary>
30-
/// <param name="query">The query.</param>
31-
/// <returns>Paged results.</returns>
32-
public override IQueryable<T> Apply(IQueryable<T> query)
33-
{
34-
query = base.Apply(query);
35-
36-
TotalItems = query.Count();
37-
38-
if (Skip > 0 || Take > 0)
17+
if (isDescending)
3918
{
40-
return query.Skip(Skip).Take(Take);
19+
_primarySortAction = q => q.OrderByDescending(sortExpression);
20+
}
21+
else
22+
{
23+
_primarySortAction = q => q.OrderBy(sortExpression);
4124
}
42-
43-
return query;
44-
}
45-
46-
/// <summary>
47-
/// Used in compiling a unique key for a query
48-
/// </summary>
49-
/// <returns>Unique key for a query</returns>
50-
public override string ToString()
51-
{
52-
return String.Format("PagingOptions<{0},{1}>\nPageSize: {2}\nPageNumber: {3}\nSort: {4}",
53-
(typeof(T)).Name,
54-
(typeof(TSortKey)).Name,
55-
PageSize,
56-
PageNumber,
57-
base.ToString()
58-
);
5925
}
6026
}
6127

@@ -103,8 +69,8 @@ public override IQueryable<T> Apply(IQueryable<T> query)
10369
/// <returns>Unique key for a query</returns>
10470
public override string ToString()
10571
{
106-
return String.Format("PagingOptions<{0}>\nPageSize: {1}\nPageNumber: {2}\nSort: {3}",
107-
(typeof(T)).Name,
72+
return string.Format("PagingOptions<{0}>\nPageSize: {1}\nPageNumber: {2}\nSort: {3}",
73+
typeof(T).Name,
10874
PageSize,
10975
PageNumber,
11076
base.ToString()

SharpRepository.Repository/Queries/SortingOptions.cs

Lines changed: 31 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -11,16 +11,9 @@ namespace SharpRepository.Repository.Queries
1111
/// </summary>
1212
/// <typeparam name="T">The entity type of the repository.</typeparam>
1313
/// <typeparam name="TSortKey">The type of the property that is being sorted.</typeparam>
14-
public class SortingOptions<T, TSortKey> : IQueryOptions<T>
14+
public class SortingOptions<T, TSortKey> : SortingOptions<T>
1515
{
16-
private readonly Func<IQueryable<T>, IOrderedQueryable<T>> _primarySortAction;
17-
private readonly IList<Func<IOrderedQueryable<T>, IOrderedQueryable<T>>> _sortActions = new List<Func<IOrderedQueryable<T>, IOrderedQueryable<T>>>();
18-
19-
// we need these fields because calling ToString on the Func's didn't include the details of the method being called so it was the same key for descending and ascending
20-
private readonly string _primarySortToString;
21-
private readonly IList<string> _sortActionsToString = new List<string>();
22-
23-
public SortingOptions(Expression<Func<T, TSortKey>> sortExpression, bool isDescending = false)
16+
public SortingOptions(Expression<Func<T, TSortKey>> sortExpression, bool isDescending = false) : base(sortExpression.ToString(), isDescending)
2417
{
2518
if (isDescending)
2619
{
@@ -30,57 +23,6 @@ public SortingOptions(Expression<Func<T, TSortKey>> sortExpression, bool isDesce
3023
{
3124
_primarySortAction = q => q.OrderBy(sortExpression);
3225
}
33-
34-
_primarySortToString = String.Format("{0}-{1}", sortExpression, isDescending);
35-
}
36-
37-
public void ThenSortBy<TNewSortKey>(Expression<Func<T, TNewSortKey>> sortExpression, bool isDescending = false)
38-
{
39-
Func<IOrderedQueryable<T>, IOrderedQueryable<T>> sortAction = null;
40-
41-
if (isDescending)
42-
{
43-
sortAction = q => q.ThenByDescending(sortExpression);
44-
}
45-
else
46-
{
47-
sortAction = q => q.ThenBy(sortExpression);
48-
}
49-
50-
_sortActions.Add(sortAction);
51-
_sortActionsToString.Add(String.Format("{0}-{1}", sortExpression, isDescending));
52-
}
53-
54-
55-
/// <summary>
56-
/// Applies sorting to the specified query.
57-
/// </summary>
58-
/// <param name="query">The query.</param>
59-
/// <returns>Sorted results.</returns>
60-
public virtual IQueryable<T> Apply(IQueryable<T> query)
61-
{
62-
IOrderedQueryable<T> sortedQuery = null;
63-
64-
if (_primarySortAction != null)
65-
{
66-
sortedQuery = _primarySortAction(query);
67-
}
68-
69-
return _sortActions.Aggregate(sortedQuery, (current, sortAction) => sortAction(current));
70-
}
71-
72-
/// <summary>
73-
/// Used in compiling a unique key for a query
74-
/// </summary>
75-
/// <returns>Unique key for a query</returns>
76-
public override string ToString()
77-
{
78-
return String.Format("SortingOptions<{0},{1}>\nSort: {2}\nExtra: {3}",
79-
(typeof(T)).Name,
80-
(typeof(TSortKey)).Name,
81-
_primarySortToString ?? "null",
82-
String.Join("-", _sortActionsToString)
83-
);
8426
}
8527
}
8628

@@ -90,12 +32,12 @@ public override string ToString()
9032
/// <typeparam name="T">The entity type of the repository.</typeparam>
9133
public class SortingOptions<T> : IQueryOptions<T>
9234
{
93-
private readonly Func<IQueryable<T>, IOrderedQueryable<T>> _primarySortAction;
94-
private readonly IList<Func<IOrderedQueryable<T>, IOrderedQueryable<T>>> _sortActions = new List<Func<IOrderedQueryable<T>, IOrderedQueryable<T>>>();
35+
protected Func<IQueryable<T>, IOrderedQueryable<T>> _primarySortAction;
36+
protected IList<Func<IOrderedQueryable<T>, IOrderedQueryable<T>>> _sortActions = new List<Func<IOrderedQueryable<T>, IOrderedQueryable<T>>>();
9537

9638
// we need these fields because calling ToString on the Func's didn't include the details of the method being called so it was the same key for descending and ascending
97-
private readonly string _primarySortToString;
98-
private readonly IList<string> _sortActionsToString = new List<string>();
39+
protected string _primarySortToString;
40+
protected IList<string> _sortActionsToString = new List<string>();
9941

10042
public SortingOptions(string sortProperty, bool isDescending = false)
10143
{
@@ -108,7 +50,7 @@ public SortingOptions(string sortProperty, bool isDescending = false)
10850
_primarySortAction = q => q.OrderByProperty(sortProperty);
10951
}
11052

111-
_primarySortToString = String.Format("{0}-{1}", sortProperty, isDescending);
53+
_primarySortToString = string.Format("{0}-{1}", sortProperty, isDescending);
11254
}
11355

11456
public void ThenSortBy(string sortProperty, bool isDescending = false)
@@ -128,6 +70,24 @@ public void ThenSortBy(string sortProperty, bool isDescending = false)
12870
_sortActionsToString.Add(String.Format("{0}-{1}", sortProperty, isDescending));
12971
}
13072

73+
public void ThenSortBy<TNewSortKey>(Expression<Func<T, TNewSortKey>> sortExpression, bool isDescending = false)
74+
{
75+
Func<IOrderedQueryable<T>, IOrderedQueryable<T>> sortAction = null;
76+
77+
if (isDescending)
78+
{
79+
sortAction = q => q.ThenByDescending(sortExpression);
80+
}
81+
else
82+
{
83+
sortAction = q => q.ThenBy(sortExpression);
84+
}
85+
86+
_sortActions.Add(sortAction);
87+
_sortActionsToString.Add(String.Format("{0}-{1}", sortExpression, isDescending));
88+
}
89+
90+
13191
/// <summary>
13292
/// Applies sorting to the specified query.
13393
/// </summary>
@@ -137,12 +97,9 @@ public virtual IQueryable<T> Apply(IQueryable<T> query)
13797
{
13898
// TODO: do we need to deal with the case where the user passes in "Name desc", should we strip the desc out, or let it override the isDescending param, or not deal with it and blame it on the user?
13999

140-
IOrderedQueryable<T> sortedQuery = null;
141-
142-
if (_primarySortAction != null)
143-
{
144-
sortedQuery = _primarySortAction(query);
145-
}
100+
IOrderedQueryable<T> sortedQuery = _primarySortAction != null
101+
? _primarySortAction(query)
102+
: null;
146103

147104
return _sortActions.Aggregate(sortedQuery, (current, sortAction) => sortAction(current));
148105
}
@@ -153,10 +110,10 @@ public virtual IQueryable<T> Apply(IQueryable<T> query)
153110
/// <returns>Unique key for a query</returns>
154111
public override string ToString()
155112
{
156-
var val = String.Format("SortingOptions<{0}>\nSort: {1}\nExtra: {2}",
157-
(typeof(T)).Name,
113+
var val = string.Format("SortingOptions<{0}>\nSort: {1}\nExtra: {2}",
114+
typeof(T).Name,
158115
_primarySortToString ?? "null",
159-
String.Join("-", _sortActionsToString)
116+
string.Join("-", _sortActionsToString)
160117
);
161118
return val;
162119
}

SharpRepository.Tests/QueryOptions/SortingOptionsTests.cs

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,26 @@ public void SortingOptions_With_Multiple_Sorting_Properties()
6161
contact.ContactTypeId.ShouldBe(2);
6262
}
6363

64+
[Test]
65+
public void SortingOptions_With_String_And_Expression_Properties()
66+
{
67+
var contacts = new List<Contact>();
68+
for (var i = 5; i >= 1; i--)
69+
{
70+
contacts.Add(new Contact { Name = "Test User " + (i % 2), ContactTypeId = i });
71+
}
72+
73+
var qo = new SortingOptions<Contact>("Name");
74+
qo.ThenSortBy(x => x.ContactTypeId);
75+
76+
var queryable = qo.Apply(contacts.AsQueryable());
77+
queryable.Count().ShouldBe(5);
78+
79+
var contact = queryable.First();
80+
contact.Name.ShouldBe("Test User 0");
81+
contact.ContactTypeId.ShouldBe(2);
82+
}
83+
6484
[Test]
6585
public void SortingOptions_Will_Sort_By_SortExpression_Asc()
6686
{
@@ -92,14 +112,34 @@ public void SortingOptions_Will_Sort_By_SortExpression_Desc()
92112
}
93113

94114
[Test]
95-
public void SortingOptions_With_Multiple_SortExpression_Properties()
115+
public void SortingOptions_With_SortExpression_And_String_Properties()
96116
{
97117
var contacts = new List<Contact>();
98118
for (var i = 5; i >= 1; i--)
99119
{
100120
contacts.Add(new Contact { Name = "Test User " + (i % 2),ContactTypeId = i});
101121
}
102122

123+
var qo = new SortingOptions<Contact, string>(x => x.Name);
124+
qo.ThenSortBy("ContactTypeId");
125+
126+
var queryable = qo.Apply(contacts.AsQueryable());
127+
queryable.Count().ShouldBe(5);
128+
129+
var contact = queryable.First();
130+
contact.Name.ShouldBe("Test User 0");
131+
contact.ContactTypeId.ShouldBe(2);
132+
}
133+
134+
[Test]
135+
public void SortingOptions_With_Multiple_SortExpression_Properties()
136+
{
137+
var contacts = new List<Contact>();
138+
for (var i = 5; i >= 1; i--)
139+
{
140+
contacts.Add(new Contact { Name = "Test User " + (i % 2), ContactTypeId = i });
141+
}
142+
103143
var qo = new SortingOptions<Contact, string>(x => x.Name);
104144
qo.ThenSortBy(x => x.ContactTypeId);
105145

SharpRepository.XmlRepository/SharpRepository.XmlRepository.csproj

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,16 +5,16 @@
55
<Description>SharpRepository generic repository implementation that stores data in a XML Serialized file</Description>
66
<Summary>Written in C#, includes support for various relational, document and object databases including Entity Framework, RavenDB, MongoDB, CouchDB and Db4o. SharpRepository includes Xml and InMemory repository implementations as well. SharpRepository offers built-in caching options for AppFabric, memcached and the standard System.Runtime.Caching. SharpRepository also supports Specifications, FetchStrategies, Batches and Traits!</Summary>
77
<PackageId>SharpRepository.XmlRepository</PackageId>
8-
<PackageVersion>2.0.1-alpha3</PackageVersion>
9-
<PackageReleaseNotes>2.0.1-alpha3: configurabile via appsettings.json</PackageReleaseNotes>
8+
<PackageVersion>2.0.2.1</PackageVersion>
9+
<PackageReleaseNotes>2.0.2: configurabile via appsettings.json, linux path !239</PackageReleaseNotes>
1010
<PackageTags>SharpRepository Repository XmlRepository Xml</PackageTags>
1111
<PackageIconUrl>https://user-images.githubusercontent.com/6349515/28491142-7b6350c4-6eeb-11e7-9c5b-e3b8ef1e73b8.png</PackageIconUrl>
1212
<PackageProjectUrl>https://github.com/SharpRepository/SharpRepository</PackageProjectUrl>
1313
<PackageLicenseUrl>https://raw.githubusercontent.com/SharpRepository/SharpRepository/master/license.txt</PackageLicenseUrl>
1414
<PackageRequireLicenseAcceptance>false</PackageRequireLicenseAcceptance>
1515
<RepositoryUrl>https://github.com/SharpRepository/SharpRepository.git</RepositoryUrl>
1616
<RepositoryType>git</RepositoryType>
17-
<Version>2.0.1-alpha3</Version>
17+
<Version>2.0.2</Version>
1818
</PropertyGroup>
1919
<ItemGroup>
2020
<Content Include="repository.xml.json">

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy