Skip to content

Commit 66af8e9

Browse files
author
Jeff Treuting
committed
HowTo's for Get Selectors, Paging and Sprting
Also, made setters publicly available for PagingOptions and SortingOptions. This can come in handy outside of the web world if you define a PagingOptions variable and then you can just change the PageNumber property as needed instead of redefining the whole object.
1 parent 4ca6a43 commit 66af8e9

File tree

5 files changed

+324
-104
lines changed

5 files changed

+324
-104
lines changed

SharpRepository.Repository/Queries/PagingOptions.cs

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ namespace SharpRepository.Repository.Queries
1111
/// <typeparam name="TSortKey">The type of the property that is being sorted.</typeparam>
1212
public class PagingOptions<T, TSortKey> : SortingOptions<T, TSortKey>
1313
{
14-
public int PageSize { get; internal set; }
15-
public int PageNumber { get; internal set; }
14+
public int PageSize { get; set; }
15+
public int PageNumber { get; set; }
1616
public int Skip { get { return (PageNumber - 1) * PageSize; } }
1717
public int Take { get { return PageSize; } }
1818
public int TotalItems { get; internal set; }
@@ -66,8 +66,8 @@ public override string ToString()
6666
/// <typeparam name="T">The entity type of the repository.</typeparam>
6767
public class PagingOptions<T> : SortingOptions<T>
6868
{
69-
public int PageSize { get; internal set; }
70-
public int PageNumber { get; internal set; }
69+
public int PageSize { get; set; }
70+
public int PageNumber { get; set; }
7171
public int Skip { get { return (PageNumber - 1) * PageSize; } }
7272
public int Take { get { return PageSize; } }
7373
public int TotalItems { get; set; }
Lines changed: 100 additions & 100 deletions
Original file line numberDiff line numberDiff line change
@@ -1,101 +1,101 @@
1-
using System;
2-
using System.Linq;
3-
using System.Linq.Expressions;
4-
using SharpRepository.Repository.Linq;
5-
6-
namespace SharpRepository.Repository.Queries
7-
{
8-
/// <summary>
9-
/// Used to define the sorting on queries run against a repository.
10-
/// </summary>
11-
/// <typeparam name="T">The entity type of the repository.</typeparam>
12-
/// <typeparam name="TSortKey">The type of the property that is being sorted.</typeparam>
13-
public class SortingOptions<T, TSortKey> : IQueryOptions<T>
14-
{
15-
public Expression<Func<T, TSortKey>> SortExpression { get; internal set; }
16-
public bool IsDescending { get; internal set; }
17-
18-
public SortingOptions(Expression<Func<T, TSortKey>> sortExpression, bool isDescending = false)
19-
{
20-
SortExpression = sortExpression;
21-
IsDescending = isDescending;
22-
}
23-
24-
/// <summary>
25-
/// Applies sorting to the specified query.
26-
/// </summary>
27-
/// <param name="query">The query.</param>
28-
/// <returns>Sorted results.</returns>
29-
public virtual IQueryable<T> Apply(IQueryable<T> query)
30-
{
31-
if (SortExpression != null)
32-
{
33-
query = IsDescending
34-
? query.OrderByDescending(SortExpression)
35-
: query.OrderBy(SortExpression);
36-
}
37-
38-
return query;
39-
}
40-
41-
/// <summary>
42-
/// Used in compiling a unique key for a query
43-
/// </summary>
44-
/// <returns>Unique key for a query</returns>
45-
public override string ToString()
46-
{
47-
return String.Format("SortingOptions<{0},{1}>\nSort Expression: {2}\nIsDescending: {3}",
48-
(typeof(T)).Name,
49-
(typeof(TSortKey)).Name,
50-
SortExpression == null ? "null" : SortExpression.ToString(),
51-
IsDescending
52-
);
53-
}
54-
}
55-
56-
/// <summary>
57-
/// Used to define the sorting on queries run against a repository.
58-
/// </summary>
59-
/// <typeparam name="T">The entity type of the repository.</typeparam>
60-
public class SortingOptions<T> : IQueryOptions<T>
61-
{
62-
public string SortProperty { get; internal set; }
63-
public bool IsDescending { get; internal set; }
64-
65-
public SortingOptions(string sortProperty, bool isDescending = false)
66-
{
67-
SortProperty = sortProperty;
68-
IsDescending = isDescending;
69-
}
70-
71-
/// <summary>
72-
/// Applies sorting to the specified query.
73-
/// </summary>
74-
/// <param name="query">The query.</param>
75-
/// <returns>Sorted results.</returns>
76-
public virtual IQueryable<T> Apply(IQueryable<T> query)
77-
{
78-
if (!String.IsNullOrEmpty(SortProperty))
79-
{
80-
// 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?
81-
var sortString = String.Format("{0}{1}", SortProperty, IsDescending ? " desc" : "");
82-
query = query.OrderBy(sortString);
83-
}
84-
85-
return query;
86-
}
87-
88-
/// <summary>
89-
/// Used in compiling a unique key for a query
90-
/// </summary>
91-
/// <returns>Unique key for a query</returns>
92-
public override string ToString()
93-
{
94-
return String.Format("SortingOptions<{0}>\nSort Property: {1}\nIsDescending: {2}",
95-
(typeof(T)).Name,
96-
SortProperty,
97-
IsDescending
98-
);
99-
}
100-
}
1+
using System;
2+
using System.Linq;
3+
using System.Linq.Expressions;
4+
using SharpRepository.Repository.Linq;
5+
6+
namespace SharpRepository.Repository.Queries
7+
{
8+
/// <summary>
9+
/// Used to define the sorting on queries run against a repository.
10+
/// </summary>
11+
/// <typeparam name="T">The entity type of the repository.</typeparam>
12+
/// <typeparam name="TSortKey">The type of the property that is being sorted.</typeparam>
13+
public class SortingOptions<T, TSortKey> : IQueryOptions<T>
14+
{
15+
public Expression<Func<T, TSortKey>> SortExpression { get; set; }
16+
public bool IsDescending { get; set; }
17+
18+
public SortingOptions(Expression<Func<T, TSortKey>> sortExpression, bool isDescending = false)
19+
{
20+
SortExpression = sortExpression;
21+
IsDescending = isDescending;
22+
}
23+
24+
/// <summary>
25+
/// Applies sorting to the specified query.
26+
/// </summary>
27+
/// <param name="query">The query.</param>
28+
/// <returns>Sorted results.</returns>
29+
public virtual IQueryable<T> Apply(IQueryable<T> query)
30+
{
31+
if (SortExpression != null)
32+
{
33+
query = IsDescending
34+
? query.OrderByDescending(SortExpression)
35+
: query.OrderBy(SortExpression);
36+
}
37+
38+
return query;
39+
}
40+
41+
/// <summary>
42+
/// Used in compiling a unique key for a query
43+
/// </summary>
44+
/// <returns>Unique key for a query</returns>
45+
public override string ToString()
46+
{
47+
return String.Format("SortingOptions<{0},{1}>\nSort Expression: {2}\nIsDescending: {3}",
48+
(typeof(T)).Name,
49+
(typeof(TSortKey)).Name,
50+
SortExpression == null ? "null" : SortExpression.ToString(),
51+
IsDescending
52+
);
53+
}
54+
}
55+
56+
/// <summary>
57+
/// Used to define the sorting on queries run against a repository.
58+
/// </summary>
59+
/// <typeparam name="T">The entity type of the repository.</typeparam>
60+
public class SortingOptions<T> : IQueryOptions<T>
61+
{
62+
public string SortProperty { get; set; }
63+
public bool IsDescending { get; set; }
64+
65+
public SortingOptions(string sortProperty, bool isDescending = false)
66+
{
67+
SortProperty = sortProperty;
68+
IsDescending = isDescending;
69+
}
70+
71+
/// <summary>
72+
/// Applies sorting to the specified query.
73+
/// </summary>
74+
/// <param name="query">The query.</param>
75+
/// <returns>Sorted results.</returns>
76+
public virtual IQueryable<T> Apply(IQueryable<T> query)
77+
{
78+
if (!String.IsNullOrEmpty(SortProperty))
79+
{
80+
// 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?
81+
var sortString = String.Format("{0}{1}", SortProperty, IsDescending ? " desc" : "");
82+
query = query.OrderBy(sortString);
83+
}
84+
85+
return query;
86+
}
87+
88+
/// <summary>
89+
/// Used in compiling a unique key for a query
90+
/// </summary>
91+
/// <returns>Unique key for a query</returns>
92+
public override string ToString()
93+
{
94+
return String.Format("SortingOptions<{0}>\nSort Property: {1}\nIsDescending: {2}",
95+
(typeof(T)).Name,
96+
SortProperty,
97+
IsDescending
98+
);
99+
}
100+
}
101101
}
Lines changed: 102 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,102 @@
1+
using System;
2+
using System.Linq;
3+
using NUnit.Framework;
4+
using SharpRepository.Repository;
5+
using Should;
6+
using SharpRepository.InMemoryRepository;
7+
8+
namespace SharpRepository.Samples
9+
{
10+
[TestFixture]
11+
public class HowToUseGetSelectors
12+
{
13+
/*
14+
* What are Get Selectors?
15+
*
16+
* There are overloaded versions of the Get, GetAll, Find and FindAll methods
17+
* that allow the use of a selector expression. You can think of it as what you
18+
* would pass to the LINQ .Select() method.
19+
*
20+
* This allows you to only bring back the columns you are looking for to decrease
21+
* network traffic, or map from your Entity to a ViewModel or other object structure
22+
* that you need it in.
23+
*
24+
* What does this look like in practice?
25+
*
26+
* Let's try it out with some Orders and a OrderRepository
27+
*/
28+
29+
public class Order
30+
{
31+
public int OrderId { get; set; }
32+
public string Name { get; set; }
33+
public double Total { get; set; }
34+
public DateTime OrderDate { get; set; }
35+
}
36+
37+
public class OrderViewModel
38+
{
39+
public string Name { get; set; }
40+
public bool IsExpensiveOrder { get; set; }
41+
}
42+
43+
[Test]
44+
public void Repository_Supports_Selectors()
45+
{
46+
var repo = new InMemoryRepository<Order>();
47+
48+
// let's add a couple of orders to work with
49+
repo.Add(new Order()
50+
{
51+
Name = "Order 1",
52+
Total = 120.00,
53+
OrderDate = new DateTime(2013, 4, 26)
54+
});
55+
56+
repo.Add(new Order()
57+
{
58+
Name = "Order 2",
59+
Total = 80.00,
60+
OrderDate = new DateTime(2013, 4, 24)
61+
});
62+
63+
// normal Get method
64+
var order = repo.Get(1);
65+
order.OrderId.ShouldEqual(1);
66+
67+
// in this case we only need the order name
68+
var orderName = repo.Get(1, x => x.Name);
69+
orderName.ShouldEqual("Order 1");
70+
71+
// we can also bring back an anonymous type if needed
72+
var anonymousType = repo.Get(1, x => new { Name = x.Name, IsExpensiveOrder = x.Total > 100.0 });
73+
anonymousType.IsExpensiveOrder.ShouldBeTrue();
74+
75+
// or we can map it to a specific type we have defined like a ViewModel
76+
var viewModel = repo.Get(1, x => new OrderViewModel() {Name = x.Name, IsExpensiveOrder = x.Total > 100.0});
77+
viewModel.IsExpensiveOrder.ShouldBeTrue();
78+
79+
// We have the same options with the GetAll, Find and FindAll as well
80+
orderName = repo.Find(x => x.OrderId == 2, x => x.Name);
81+
orderName.ShouldEqual("Order 2");
82+
83+
// we can also bring back an anonymous type if needed
84+
var anonymousTypes = repo.GetAll(x => new { Name = x.Name, IsExpensiveOrder = x.Total > 100.0 }).ToList();
85+
anonymousTypes.Count.ShouldEqual(2);
86+
anonymousTypes.First().Name.ShouldEqual("Order 1");
87+
anonymousTypes.First().IsExpensiveOrder.ShouldBeTrue();
88+
89+
anonymousTypes.Last().Name.ShouldEqual("Order 2");
90+
anonymousTypes.Last().IsExpensiveOrder.ShouldBeFalse();
91+
92+
// or we can map it to a specific type we have defined like a ViewModel
93+
var viewModels = repo.FindAll(x => x.OrderId < 5, x => new OrderViewModel() { Name = x.Name, IsExpensiveOrder = x.Total > 100.0 }).ToList();
94+
viewModels.Count.ShouldEqual(2);
95+
viewModels.First().Name.ShouldEqual("Order 1");
96+
viewModels.First().IsExpensiveOrder.ShouldBeTrue();
97+
98+
viewModels.Last().Name.ShouldEqual("Order 2");
99+
viewModels.Last().IsExpensiveOrder.ShouldBeFalse();
100+
}
101+
}
102+
}

0 commit comments

Comments
 (0)