Skip to content

Commit 9eda8ed

Browse files
committed
comments
1 parent 0402867 commit 9eda8ed

File tree

6 files changed

+102
-46
lines changed

6 files changed

+102
-46
lines changed

src/AutSoft.Core/Exceptions/EntityNotFoundException.cs

Lines changed: 19 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,20 @@ public sealed class EntityNotFoundException : Exception
1212
/// </summary>
1313
/// <param name="message">Exception's message</param>
1414
/// <param name="innerException">Related tiggering exception</param>
15-
private EntityNotFoundException(string message, Exception innerException)
15+
private EntityNotFoundException(string message, Exception? innerException = null)
1616
: base(message, innerException)
1717
{
1818
}
1919

20+
/// <summary>
21+
/// Foctory method which creates an <see cref="EntityNotFoundException"/> with a standard message.
22+
/// </summary>
23+
/// <typeparam name="T">Not found entity's type</typeparam>
24+
/// <param name="id">Entity's id</param>
25+
/// <returns>Returns <see cref="EntityNotFoundException"/> with a standard message.</returns>
26+
public static EntityNotFoundException CreateForType<T>(long? id)
27+
=> new($"Cannot find entity of type {typeof(T).Name}" + (id.HasValue ? $" with id={id}" : string.Empty));
28+
2029
/// <summary>
2130
/// Foctory method which creates an <see cref="EntityNotFoundException"/> with a standard message.
2231
/// </summary>
@@ -27,6 +36,15 @@ private EntityNotFoundException(string message, Exception innerException)
2736
public static EntityNotFoundException CreateForType<T>(Exception innerException, long? id)
2837
=> new($"Cannot find entity of type {typeof(T).Name}" + (id.HasValue ? $" with id={id}" : string.Empty), innerException);
2938

39+
/// <summary>
40+
/// Foctory method which creates an <see cref="EntityNotFoundException"/> with a standard message.
41+
/// </summary>
42+
/// <typeparam name="T">Not found entity's type</typeparam>
43+
/// <param name="queryParameters">Search parameters which occur this error</param>
44+
/// <returns>Returns <see cref="EntityNotFoundException"/> with a standard message.</returns>
45+
public static EntityNotFoundException CreateForTypeCustomParams<T>(params object[] queryParameters)
46+
=> new($"Cannot find entity of type {typeof(T).Name} with params:" + string.Join("; ", queryParameters));
47+
3048
/// <summary>
3149
/// Foctory method which creates an <see cref="EntityNotFoundException"/> with a standard message.
3250
/// </summary>
Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,17 @@
11
namespace AutSoft.Linq.Models;
22

3+
/// <summary>
4+
/// Order direction of a query
5+
/// </summary>
36
public enum OrderDirection
47
{
8+
/// <summary>
9+
/// Ascending order direction
10+
/// </summary>
511
Ascending = 0,
12+
13+
/// <summary>
14+
/// Descending order direction
15+
/// </summary>
616
Descending = 1,
717
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,27 @@
11
namespace AutSoft.Linq.Models;
22

3+
/// <summary>
4+
/// Common query parameters for a paged request (mostly for grids and lists)
5+
/// </summary>
36
public class PageRequest
47
{
8+
/// <summary>
9+
/// Gets or sets requested page's size, default is 50
10+
/// </summary>
511
public int PageSize { get; set; } = 50;
12+
13+
/// <summary>
14+
/// Gets or sets requested page, 0 represents first page
15+
/// </summary>
616
public int Page { get; set; }
17+
18+
/// <summary>
19+
/// Gets or sets order by based on this property's name
20+
/// </summary>
721
public string? OrderBy { get; set; }
22+
23+
/// <summary>
24+
/// Gets or sets order direction, default is <see cref="OrderDirection.Ascending"/>
25+
/// </summary>
826
public OrderDirection OrderDirection { get; set; } = OrderDirection.Ascending;
927
}

src/AutSoft.Linq/Models/PageResponse.cs

Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,18 @@
11
namespace AutSoft.Linq.Models;
22

3+
/// <summary>
4+
/// Wraps a page of the requested objects
5+
/// </summary>
6+
/// <typeparam name="T">Type of requested objects</typeparam>
37
public class PageResponse<T>
48
{
9+
/// <summary>
10+
/// Initializes a new instance of the <see cref="PageResponse{T}"/> class.
11+
/// </summary>
12+
/// <param name="results">List of objects of the current page</param>
13+
/// <param name="currentPage">Current page's index (start's from 0)</param>
14+
/// <param name="totalCount">Total object count on all pages</param>
15+
/// <param name="pageCount">Total page count</param>
516
public PageResponse(List<T> results, int currentPage, int totalCount, int pageCount)
617
{
718
Results = results;
@@ -10,9 +21,23 @@ public PageResponse(List<T> results, int currentPage, int totalCount, int pageCo
1021
PageCount = pageCount;
1122
}
1223

24+
/// <summary>
25+
/// Gets or sets objects of the current page
26+
/// </summary>
1327
public List<T> Results { get; set; }
1428

29+
/// <summary>
30+
/// Gets or sets current page's index (start's from 0)
31+
/// </summary>
1532
public int CurrentPage { get; set; }
33+
34+
/// <summary>
35+
/// Gets or sets total page count
36+
/// </summary>
1637
public int PageCount { get; set; }
38+
39+
/// <summary>
40+
/// Gets or sets total object count on all pages
41+
/// </summary>
1742
public int TotalCount { get; set; }
1843
}

src/AutSoft.Linq/Queryable/FirstAndSingleExtensions.cs

Lines changed: 27 additions & 45 deletions
Original file line numberDiff line numberDiff line change
@@ -6,56 +6,38 @@
66

77
namespace AutSoft.Linq.Queryable;
88

9+
/// <summary>
10+
/// Extensions methods for <see cref="IQueryable{T}"/> with extended functionality for Single and First methods/>
11+
/// </summary>
912
public static class FirstAndSingleExtensions
1013
{
11-
public static async Task<T> SingleEntityAsync<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate, long entityId)
14+
/// <summary>
15+
/// Similar to <see cref="EntityFrameworkQueryableExtensions.SingleOrDefaultAsync{TSource}(IQueryable{TSource}, CancellationToken)"/>
16+
/// </summary>
17+
/// <typeparam name="T">The type of the elements of <paramref name="source" />.</typeparam>
18+
/// <param name="source">An <see cref="IQueryable{T}" /> to return the single element of.</param>
19+
/// <param name="predicate">A function to test an element for a condition.</param>
20+
/// <param name="entityId">Identifier of the requested element</param>
21+
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
22+
/// <exception cref="EntityNotFoundException">Throws when no result found</exception>
23+
public static async Task<T> SingleEntityAsync<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate, long entityId, CancellationToken cancellationToken = default)
1224
{
13-
try
14-
{
15-
return await source.SingleAsync(predicate);
16-
}
17-
catch (InvalidOperationException e)
18-
{
19-
// Single throws an InvalidOperationException when no entities are found
20-
throw EntityNotFoundException.CreateForType<T>(e, entityId);
21-
}
25+
return await source.SingleOrDefaultAsync(predicate, cancellationToken)
26+
?? throw EntityNotFoundException.CreateForType<T>(entityId);
2227
}
2328

24-
public static async Task<T> SingleEntityAsync<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate, params object[] queryParameters)
29+
/// <summary>
30+
/// Similar to <see cref="EntityFrameworkQueryableExtensions.SingleOrDefaultAsync{TSource}(IQueryable{TSource}, CancellationToken)"/>
31+
/// </summary>
32+
/// <typeparam name="T">The type of the elements of <paramref name="source" />.</typeparam>
33+
/// <param name="source">An <see cref="IQueryable{T}" /> to return the single element of.</param>
34+
/// <param name="predicate">A function to test an element for a condition.</param>
35+
/// <param name="queryParameters">Query parameters of the requested element</param>
36+
/// <param name="cancellationToken">A <see cref="CancellationToken" /> to observe while waiting for the task to complete.</param>
37+
/// <exception cref="EntityNotFoundException">Throws when no result found</exception>
38+
public static async Task<T> SingleEntityAsync<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate, object[] queryParameters, CancellationToken cancellationToken = default)
2539
{
26-
try
27-
{
28-
return await source.SingleAsync(predicate);
29-
}
30-
catch (InvalidOperationException e)
31-
{
32-
// Single throws an InvalidOperationException when no entities are found
33-
throw EntityNotFoundException.CreateForTypeCustomParams<T>(e, queryParameters);
34-
}
35-
}
36-
37-
public static T SingleEntity<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate, params object[] queryParameters)
38-
{
39-
try
40-
{
41-
return source.Single(predicate);
42-
}
43-
catch (InvalidOperationException e)
44-
{
45-
// Single throws an InvalidOperationException when no entities are found
46-
throw EntityNotFoundException.CreateForTypeCustomParams<T>(e, queryParameters);
47-
}
48-
}
49-
50-
public static async Task<T> FirstEntityAsync<T>(this IQueryable<T> source, Expression<Func<T, bool>> predicate)
51-
{
52-
try
53-
{
54-
return await source.FirstAsync(predicate);
55-
}
56-
catch (InvalidOperationException e)
57-
{
58-
throw EntityNotFoundException.CreateForType<T>(e, default);
59-
}
40+
return await source.SingleAsync(predicate, cancellationToken)
41+
?? throw EntityNotFoundException.CreateForTypeCustomParams<T>(queryParameters);
6042
}
6143
}

src/AutSoft.Linq/Queryable/NotSortableAttribute.cs

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
namespace AutSoft.Linq.Queryable;
22

3+
/// <summary>
4+
/// Indicates if a property is not sortable by <see cref="OrderByExtensions"/>
5+
/// </summary>
36
[AttributeUsage(AttributeTargets.Property, AllowMultiple = false)]
47
public class NotSortableAttribute : Attribute
58
{

0 commit comments

Comments
 (0)