Skip to content

Commit 73fb5c3

Browse files
committed
paging support (#16)
1 parent 1b200ff commit 73fb5c3

File tree

7 files changed

+357
-8
lines changed

7 files changed

+357
-8
lines changed

src/System.Linq.Dynamic.Core.SL50/System.Linq.Dynamic.Core.SL50.csproj

+6
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,12 @@
122122
<Compile Include="..\System.Linq.Dynamic.Core\IDynamicLinkTypeProvider.cs">
123123
<Link>IDynamicLinkTypeProvider.cs</Link>
124124
</Compile>
125+
<Compile Include="..\System.Linq.Dynamic.Core\MethodInfoHelper.cs">
126+
<Link>MethodInfoHelper.cs</Link>
127+
</Compile>
128+
<Compile Include="..\System.Linq.Dynamic.Core\PagedResult.cs">
129+
<Link>PagedResult.cs</Link>
130+
</Compile>
125131
<Compile Include="..\System.Linq.Dynamic.Core\Res.cs">
126132
<Link>Res.cs</Link>
127133
</Compile>

src/System.Linq.Dynamic.Core/BasicQueryable.cs

+156-3
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
using System.Collections;
22
using System.Collections.Generic;
3+
using System.Diagnostics;
4+
using System.Linq.Dynamic.Core.Extensions;
35
using System.Linq.Dynamic.Core.Validation;
46
using System.Linq.Expressions;
7+
using System.Reflection;
58
using JetBrains.Annotations;
69

710
namespace System.Linq.Dynamic.Core
@@ -14,6 +17,77 @@ namespace System.Linq.Dynamic.Core
1417
public static class BasicQueryable
1518
{
1619
#region IQueryable Adjustors
20+
/// <summary>
21+
/// Returns the elements as paged.
22+
/// </summary>
23+
/// <param name="source">The sequence to return elements from.</param>
24+
/// <param name="page">The page to return.</param>
25+
/// <param name="pageSize">The number of elements per page.</param>
26+
/// <returns>A <see cref="IQueryable"/> that contains the paged elements.</returns>
27+
public static IQueryable Page([NotNull] this IQueryable source, int page, int pageSize)
28+
{
29+
Check.NotNull(source, nameof(source));
30+
Check.Condition(page, p => p > 0, nameof(page));
31+
Check.Condition(pageSize, ps => ps > 0, nameof(pageSize));
32+
33+
return source.Skip((page - 1) * pageSize).Take(pageSize);
34+
}
35+
36+
public static IQueryable<TSource> Page<TSource>([NotNull] this IQueryable<TSource> source, int page, int pageSize)
37+
{
38+
Check.NotNull(source, nameof(source));
39+
Check.Condition(page, p => p > 0, nameof(page));
40+
Check.Condition(pageSize, ps => ps > 0, nameof(pageSize));
41+
42+
return Queryable.Take(Queryable.Skip(source, (page - 1) * pageSize), pageSize);
43+
}
44+
45+
/// <summary>
46+
/// Returns the elements as paged and include the CurrentPage, PageCount, PageSize and RowCount.
47+
/// http://weblogs.asp.net/gunnarpeipman/returning-paged-results-from-repositories-using-pagedresult-lt-t-gt
48+
/// </summary>
49+
/// <param name="source">The sequence to return elements from.</param>
50+
/// <param name="page">The page to return.</param>
51+
/// <param name="pageSize">The number of elements per page.</param>
52+
/// <returns>PagedResult</returns>
53+
public static PagedResult PageResult([NotNull] this IQueryable source, int page, int pageSize)
54+
{
55+
Check.NotNull(source, nameof(source));
56+
Check.Condition(page, p => p > 0, nameof(page));
57+
Check.Condition(pageSize, ps => ps > 0, nameof(pageSize));
58+
59+
var result = new PagedResult
60+
{
61+
CurrentPage = page,
62+
PageSize = pageSize,
63+
RowCount = source.Count()
64+
};
65+
66+
result.PageCount = (int)Math.Ceiling((double)result.RowCount / pageSize);
67+
result.Queryable = Page(source, page, pageSize);
68+
69+
return result;
70+
}
71+
72+
public static PagedResult<TSource> PageResult<TSource>([NotNull] this IQueryable<TSource> source, int page, int pageSize)
73+
{
74+
Check.NotNull(source, nameof(source));
75+
Check.Condition(page, p => p > 0, nameof(page));
76+
Check.Condition(pageSize, ps => ps > 0, nameof(pageSize));
77+
78+
var result = new PagedResult<TSource>
79+
{
80+
CurrentPage = page,
81+
PageSize = pageSize,
82+
RowCount = Queryable.Count(source)
83+
};
84+
85+
result.PageCount = (int)Math.Ceiling((double)result.RowCount / pageSize);
86+
result.Queryable = Page(source, page, pageSize);
87+
88+
return result;
89+
}
90+
1791
/// <summary>
1892
/// Returns a specified number of contiguous elements from the start of a sequence.
1993
/// </summary>
@@ -23,7 +97,7 @@ public static class BasicQueryable
2397
public static IQueryable Take([NotNull] this IQueryable source, int count)
2498
{
2599
Check.NotNull(source, nameof(source));
26-
Check.Condition(count, x => x > 0, nameof(source));
100+
Check.Condition(count, x => x > 0, nameof(count));
27101

28102
return source.Provider.CreateQuery(
29103
Expression.Call(
@@ -32,6 +106,14 @@ public static IQueryable Take([NotNull] this IQueryable source, int count)
32106
source.Expression, Expression.Constant(count)));
33107
}
34108

109+
public static IQueryable<TSource> Take<TSource>([NotNull] this IQueryable<TSource> source, int count)
110+
{
111+
Check.NotNull(source, nameof(source));
112+
Check.Condition(count, x => x > 0, nameof(count));
113+
114+
return Queryable.Take(source, count);
115+
}
116+
35117
/// <summary>
36118
/// Bypasses a specified number of elements in a sequence and then returns the remaining elements.
37119
/// </summary>
@@ -41,7 +123,7 @@ public static IQueryable Take([NotNull] this IQueryable source, int count)
41123
public static IQueryable Skip([NotNull] this IQueryable source, int count)
42124
{
43125
Check.NotNull(source, nameof(source));
44-
Check.Condition(count, x => x >= 0, nameof(source));
126+
Check.Condition(count, x => x >= 0, nameof(count));
45127

46128
//no need to skip if count is zero
47129
if (count == 0)
@@ -54,6 +136,14 @@ public static IQueryable Skip([NotNull] this IQueryable source, int count)
54136
source.Expression, Expression.Constant(count)));
55137
}
56138

139+
public static IQueryable<TSource> Skip<TSource>([NotNull] this IQueryable<TSource> source, int count)
140+
{
141+
Check.NotNull(source, nameof(source));
142+
Check.Condition(count, x => x >= 0, nameof(count));
143+
144+
return count == 0 ? source : Queryable.Skip(source, count);
145+
}
146+
57147
/// <summary>
58148
/// Inverts the order of the elements in a sequence.
59149
/// </summary>
@@ -83,6 +173,20 @@ public static bool Any([NotNull] this IQueryable source)
83173
Expression.Call(
84174
typeof(Queryable), "Any",
85175
new[] { source.ElementType }, source.Expression));
176+
177+
//return (bool) source.Provider.Execute(
178+
// Expression.Call(
179+
// null,
180+
// MethodInfoHelper.GetMethodInfoOf(() => BasicQueryable.Any(default(IQueryable))),
181+
// new Expression[] { source.Expression }
182+
// ));
183+
}
184+
185+
public static bool Any<TSource>([NotNull] this IQueryable<TSource> source)
186+
{
187+
Check.NotNull(source, nameof(source));
188+
189+
return Queryable.Any(source);
86190
}
87191

88192
/// <summary>
@@ -100,6 +204,13 @@ public static int Count([NotNull] this IQueryable source)
100204
new[] { source.ElementType }, source.Expression));
101205
}
102206

207+
public static int Count<TSource>([NotNull] this IQueryable<TSource> source)
208+
{
209+
Check.NotNull(source, nameof(source));
210+
211+
return Queryable.Count(source);
212+
}
213+
103214
/// <summary>
104215
/// Computes the sum of a sequence of numeric values.
105216
/// </summary>
@@ -137,6 +248,13 @@ public static dynamic Single([NotNull] this IQueryable source)
137248
new[] { source.ElementType }, source.Expression));
138249
}
139250

251+
public static TSource Single<TSource>([NotNull] this IQueryable<TSource> source)
252+
{
253+
Check.NotNull(source, nameof(source));
254+
255+
return Queryable.Single(source);
256+
}
257+
140258
/// <summary>
141259
/// Returns the only element of a sequence, or a default value if the sequence
142260
/// is empty; this method throws an exception if there is more than one element
@@ -157,6 +275,13 @@ public static dynamic SingleOrDefault([NotNull] this IQueryable source)
157275
new[] { source.ElementType }, source.Expression));
158276
}
159277

278+
public static TSource SingleOrDefault<TSource>([NotNull] this IQueryable<TSource> source)
279+
{
280+
Check.NotNull(source, nameof(source));
281+
282+
return Queryable.SingleOrDefault(source);
283+
}
284+
160285
/// <summary>
161286
/// Returns the first element of a sequence.
162287
/// </summary>
@@ -175,6 +300,13 @@ public static dynamic First([NotNull] this IQueryable source)
175300
new[] { source.ElementType }, source.Expression));
176301
}
177302

303+
public static TSource First<TSource>([NotNull] this IQueryable<TSource> source)
304+
{
305+
Check.NotNull(source, nameof(source));
306+
307+
return Queryable.First(source);
308+
}
309+
178310
/// <summary>
179311
/// Returns the first element of a sequence, or a default value if the sequence contains no elements.
180312
/// </summary>
@@ -193,6 +325,13 @@ public static dynamic FirstOrDefault([NotNull] this IQueryable source)
193325
new[] { source.ElementType }, source.Expression));
194326
}
195327

328+
public static TSource FirstOrDefault<TSource>([NotNull] this IQueryable<TSource> source)
329+
{
330+
Check.NotNull(source, nameof(source));
331+
332+
return Queryable.FirstOrDefault(source);
333+
}
334+
196335
/// <summary>
197336
/// Returns the last element of a sequence.
198337
/// </summary>
@@ -211,6 +350,13 @@ public static dynamic Last([NotNull] this IQueryable source)
211350
new[] { source.ElementType }, source.Expression));
212351
}
213352

353+
public static TSource Last<TSource>([NotNull] this IQueryable<TSource> source)
354+
{
355+
Check.NotNull(source, nameof(source));
356+
357+
return Queryable.Last(source);
358+
}
359+
214360
/// <summary>
215361
/// Returns the last element of a sequence, or a default value if the sequence contains no elements.
216362
/// </summary>
@@ -229,6 +375,13 @@ public static dynamic LastOrDefault([NotNull] this IQueryable source)
229375
new[] { source.ElementType }, source.Expression));
230376
}
231377

378+
public static TSource LastOrDefault<TSource>([NotNull] this IQueryable<TSource> source)
379+
{
380+
Check.NotNull(source, nameof(source));
381+
382+
return Queryable.LastOrDefault(source);
383+
}
384+
232385
#if NET35
233386
/// <summary>
234387
/// Returns the input typed as <see cref="IEnumerable{T}"/> of <see cref="object"/>./>
@@ -300,4 +453,4 @@ public static List<T> ToDynamicList<T>([NotNull] this IEnumerable source)
300453
#endif
301454
#endregion
302455
}
303-
}
456+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
using System.Linq.Expressions;
2+
using System.Reflection;
3+
4+
namespace System.Linq.Dynamic.Core
5+
{
6+
internal class MethodInfoHelper
7+
{
8+
public static MethodInfo GetMethodInfoOf<T>(Expression<Func<T>> expression)
9+
{
10+
var body = (MethodCallExpression)expression.Body;
11+
return body.Method;
12+
}
13+
}
14+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+

2+
namespace System.Linq.Dynamic.Core
3+
{
4+
public class PagedResult
5+
{
6+
public IQueryable Queryable { get; set; }
7+
8+
public int CurrentPage { get; set; }
9+
10+
public int PageCount { get; set; }
11+
12+
public int PageSize { get; set; }
13+
14+
public int RowCount { get; set; }
15+
}
16+
17+
public class PagedResult<TSource>
18+
{
19+
public IQueryable<TSource> Queryable { get; set; }
20+
21+
public int CurrentPage { get; set; }
22+
23+
public int PageCount { get; set; }
24+
25+
public int PageSize { get; set; }
26+
27+
public int RowCount { get; set; }
28+
}
29+
}

0 commit comments

Comments
 (0)