1111
1212namespace AutSoft . Linq . Queryable ;
1313
14+ /// <summary>
15+ /// Extensions methods for <see cref="IQueryable{T}"/> with extended functionality fo element ordering
16+ /// </summary>
1417public static class OrderByExtensions
1518{
19+ /// <summary>
20+ /// Determine that a property has <see cref="NotSortableAttribute"/>
21+ /// </summary>
22+ /// <param name="propertyInfo">Property to examine</param>
23+ /// <returns>True if the property has <see cref="NotSortableAttribute"/></returns>
1624 public static bool IsSortable ( this PropertyInfo propertyInfo )
1725 {
1826 return ! Attribute . IsDefined ( propertyInfo , typeof ( NotSortableAttribute ) ) ;
1927 }
2028
29+ /// <summary>
30+ /// OrderBy where the direction is coming from a parameter in order to write order by with fluent syntax
31+ /// </summary>
32+ /// <typeparam name="TSource">Element's type</typeparam>
33+ /// <typeparam name="TKey">Ordering key's type</typeparam>
34+ /// <param name="source">An <see cref="IQueryable{T}" /> to order</param>
35+ /// <param name="keySelector">Expression of the ordering key</param>
36+ /// <param name="orderDirection">Direction of ordering represents with <see cref="OrderDirection"/> enum</param>
37+ /// <returns><see cref="IQueryable{T}" /> with ordering information</returns>
2138 public static IOrderedQueryable < TSource > OrderBy < TSource , TKey > (
2239 this IQueryable < TSource > source ,
2340 Expression < Func < TSource , TKey > > keySelector ,
@@ -28,6 +45,37 @@ public static IOrderedQueryable<TSource> OrderBy<TSource, TKey>(
2845 : source . OrderBy ( keySelector ) ;
2946 }
3047
48+ /// <summary>
49+ /// ThenBy where the direction is coming from a parameter in order to write order by with fluent syntax
50+ /// </summary>
51+ /// <typeparam name="TSource">Element's type</typeparam>
52+ /// <typeparam name="TKey">Ordering key's type</typeparam>
53+ /// <param name="source">An <see cref="IQueryable{T}" /> to order</param>
54+ /// <param name="keySelector">Expression of the ordering key</param>
55+ /// <param name="orderDirection">Direction of ordering represents with <see cref="OrderDirection"/> enum</param>
56+ /// <returns><see cref="IQueryable{T}" /> with ordering information</returns>
57+ public static IOrderedQueryable < TSource > ThenBy < TSource , TKey > (
58+ this IOrderedQueryable < TSource > source ,
59+ Expression < Func < TSource , TKey > > keySelector ,
60+ OrderDirection orderDirection )
61+ {
62+ return orderDirection == OrderDirection . Descending
63+ ? source . ThenByDescending ( keySelector )
64+ : source . ThenBy ( keySelector ) ;
65+ }
66+
67+ /// <summary>
68+ /// OrderBy where the desired ordering is coming from a <see cref="PageRequest"/>
69+ /// </summary>
70+ /// <typeparam name="TSource">Element's type</typeparam>
71+ /// <param name="source">An <see cref="IQueryable{T}" /> to order</param>
72+ /// <param name="pageRequest">A page request which contains the desired column's name to order.</param>
73+ /// <param name="defaultOrderingSelector">If the page request does not define any ordering information</param>
74+ /// <returns><see cref="IQueryable{T}" /> with ordering information</returns>
75+ /// <remarks>
76+ /// This overload fits if the page request contains ordering information in entity model level.
77+ /// If you use AutoMapper's <see cref="IMapper.ProjectTo"/> consider to use overloads with TDto type parameters
78+ /// </remarks>
3179 public static IOrderedQueryable < TSource > OrderBy < TSource > (
3280 this IQueryable < TSource > source ,
3381 PageRequest pageRequest ,
@@ -40,6 +88,17 @@ public static IOrderedQueryable<TSource> OrderBy<TSource>(
4088 pageRequest . OrderDirection ) ;
4189 }
4290
91+ /// <summary>
92+ /// OrderBy where the desired ordering is coming from a <see cref="PageRequest"/>
93+ /// and mapping expression calculated based on the provided mapping configuration
94+ /// </summary>
95+ /// <typeparam name="TSource">Element's type</typeparam>
96+ /// <typeparam name="TDto">Target DTO's type to find mapping information</typeparam>
97+ /// <param name="source">An <see cref="IQueryable{T}" /> to order</param>
98+ /// <param name="pageRequest">A page request which contains the desired column's name to order.</param>
99+ /// <param name="defaultOrderingSelector">If the page request does not define any ordering information</param>
100+ /// <param name="mappings">AutoMapper mapping configuration which contains mapping expressions for TSource -> TDto type conversion</param>
101+ /// <returns><see cref="IQueryable{T}" /> with ordering information</returns>
43102 public static IOrderedQueryable < TSource > OrderBy < TSource , TDto > (
44103 this IQueryable < TSource > source ,
45104 PageRequest pageRequest ,
@@ -51,6 +110,18 @@ public static IOrderedQueryable<TSource> OrderBy<TSource, TDto>(
51110 return source . OrderBy ( orderKeySelector , pageRequest . OrderDirection ) ;
52111 }
53112
113+ /// <summary>
114+ /// OrderBy where the desired ordering is coming from a <see cref="PageRequest"/>
115+ /// and mapping expression calculated based on the provided mapping configuration
116+ /// </summary>
117+ /// <typeparam name="TSource">Element's type</typeparam>
118+ /// <typeparam name="TDto">Target DTO's type to find mapping information</typeparam>
119+ /// <param name="source">An <see cref="IQueryable{T}" /> to order</param>
120+ /// <param name="pageRequest">A page request which contains the desired column's name to order.</param>
121+ /// <param name="defaultOrderingSelector">If the page request does not define any ordering information</param>
122+ /// <param name="defaultOrderDirection">Ordering direction for <paramref name="defaultOrderingSelector"/></param>
123+ /// <param name="mappings">AutoMapper mapping configuration which contains mapping expressions for TSource -> TDto type conversion</param>
124+ /// <returns><see cref="IQueryable{T}" /> with ordering information</returns>
54125 public static IOrderedQueryable < TSource > OrderBy < TSource , TDto > (
55126 this IQueryable < TSource > source ,
56127 PageRequest pageRequest ,
@@ -66,30 +137,17 @@ public static IOrderedQueryable<TSource> OrderBy<TSource, TDto>(
66137 return source . OrderBy ( orderKeySelector , pageRequest . OrderDirection ) ;
67138 }
68139
69- public static IOrderedQueryable < TSource > ThenBy < TSource , TKey > (
70- this IOrderedQueryable < TSource > source ,
71- Expression < Func < TSource , TKey > > keySelector ,
72- OrderDirection orderDirection )
73- {
74- if ( orderDirection == OrderDirection . Descending )
75- return source . ThenByDescending ( keySelector ) ;
76-
77- return source . ThenBy ( keySelector ) ;
78- }
79-
80140 private static Expression < Func < TSource , object > > GetOrderKeySelector < TSource , TDto > (
81141 PageRequest pageRequest ,
82142 Expression < Func < TSource , object > > defaultOrderingSelector ,
83143 IConfigurationProvider mappings )
84144 {
85145 if ( ! string . IsNullOrEmpty ( pageRequest . OrderBy ) )
86146 {
87- // A kliens olyan property-re szeretne rendezni,
88- // amire a lekérdezésben nincs ráhatásunk,
89- // vagy nem szeretnénk engedni a rendezést
147+ // The caller want to order based on a not existed or an unsortable property
90148 var pi = typeof ( TDto ) . GetProperty ( pageRequest . OrderBy ) ;
91149 if ( pi ? . IsSortable ( ) != true )
92- throw new ValidationException ( pageRequest . OrderBy , "Ezt az oszlopot nem lehet sorba rendezni !" ) ;
150+ throw new ValidationException ( pageRequest . OrderBy , "Cannot sort based on this property !" ) ;
93151 }
94152
95153 var orderKeySelector = defaultOrderingSelector ;
0 commit comments