22using GridifyExtensions . Enums ;
33using GridifyExtensions . Models ;
44using Microsoft . EntityFrameworkCore ;
5+ using System . Collections ;
56using System . Linq . Expressions ;
67
78namespace GridifyExtensions . Extensions ;
@@ -15,7 +16,9 @@ public static async Task<PagedResponse<TDto>> FilterOrderAndGetPagedAsync<TEntit
1516 Expression < Func < TEntity , TDto > > selectExpression , CancellationToken cancellationToken = default )
1617 where TEntity : class
1718 {
18- var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as GridifyMapper < TEntity > ;
19+ var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as FilterMapper < TEntity > ;
20+
21+ model . OrderBy ??= mapper ! . GetDefaultOrderExpression ( ) ;
1922
2023 query = query . ApplyFilteringAndOrdering ( model , mapper ) ;
2124
@@ -37,15 +40,17 @@ public static Task<PagedResponse<TEntity>> FilterOrderAndGetPagedAsync<TEntity>(
3740 public static IQueryable < TEntity > ApplyFilter < TEntity > ( this IQueryable < TEntity > query , GridifyQueryModel model )
3841 where TEntity : class
3942 {
40- var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as GridifyMapper < TEntity > ;
43+ var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as FilterMapper < TEntity > ;
4144
4245 return query . AsNoTracking ( ) . ApplyFiltering ( model , mapper ) ;
4346 }
4447
4548 public static IQueryable < TEntity > ApplyOrder < TEntity > ( this IQueryable < TEntity > query , GridifyQueryModel model )
4649 where TEntity : class
4750 {
48- var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as GridifyMapper < TEntity > ;
51+ var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as FilterMapper < TEntity > ;
52+
53+ model . OrderBy ??= mapper ! . GetDefaultOrderExpression ( ) ;
4954
5055 return query . AsNoTracking ( ) . ApplyOrdering ( model , mapper ) ;
5156 }
@@ -66,10 +71,25 @@ public static async Task<PagedResponse<object>> ColumnDistinctValuesAsync<TEntit
6671 ColumnDistinctValueQueryModel model , Func < byte [ ] , string > ? decryptor = default ,
6772 CancellationToken cancellationToken = default )
6873 {
69- var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as GridifyMapper < TEntity > ;
74+ var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as FilterMapper < TEntity > ;
7075
71- if ( ! model . Encrypted )
76+ if ( ! mapper ! . IsEncrypted ( model . PropertyName ) )
7277 {
78+ if ( mapper ! . IsArray ( model . PropertyName ) )
79+ {
80+
81+ var data = await query . ApplyFiltering ( model , mapper )
82+ . ApplySelect ( model . PropertyName , mapper )
83+ . ToArrayAsync ( cancellationToken ) ;
84+
85+ var result = data . SelectMany ( item => ( ( IList ) item ) . Cast < object > ( ) )
86+ . Distinct ( )
87+ . OrderBy ( x => x )
88+ . ToList ( ) ;
89+
90+ return new PagedResponse < object > ( result , model . Page , model . PageSize , result . Count ) ;
91+ }
92+
7393 return await query
7494 . ApplyFiltering ( model , mapper )
7595 . ApplySelect ( model . PropertyName , mapper )
@@ -92,40 +112,31 @@ public static async Task<PagedResponse<object>> ColumnDistinctValuesAsync<TEntit
92112 return new PagedResponse < object > ( [ decryptedItem ] , 1 , 1 , 1 ) ;
93113 }
94114
95- private static Expression < Func < T , object > > CreateSelector < T > ( string propertyName )
96- {
97- var parameter = Expression . Parameter ( typeof ( T ) , "x" ) ;
98- var property = Expression . Property ( parameter , propertyName ) ;
99- var converted = Expression . Convert ( property , typeof ( object ) ) ;
100-
101- return Expression . Lambda < Func < T , object > > ( converted , parameter ) ;
102- }
103-
104115 public static async Task < object > AggregateAsync < TEntity > ( this IQueryable < TEntity > query ,
105- AggregateQueryModel model ,
106- CancellationToken cancellationToken = default )
107- where TEntity : class
116+ AggregateQueryModel model ,
117+ CancellationToken cancellationToken = default )
118+ where TEntity : class
108119 {
109120 var aggregateProperty = model . PropertyName ;
110121
111- var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as GridifyMapper < TEntity > ;
122+ var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as FilterMapper < TEntity > ;
112123
113- var query2 = query . ApplyFiltering ( model , mapper ) . ApplySelect ( aggregateProperty , mapper ) ;
124+ var filteredQuery = query . ApplyFiltering ( model , mapper ) . ApplySelect ( aggregateProperty , mapper ) ;
114125
115126 return model . AggregateType switch
116127 {
117- AggregateType . UniqueCount => await query2 . Distinct ( ) . CountAsync ( cancellationToken ) ,
118- AggregateType . Sum => await query2 . SumAsync ( x => ( decimal ) x , cancellationToken ) ,
119- AggregateType . Average => await query2 . AverageAsync ( x => ( decimal ) x , cancellationToken ) ,
120- AggregateType . Min => await query2 . MinAsync ( cancellationToken ) ,
121- AggregateType . Max => await query2 . MaxAsync ( cancellationToken ) ,
128+ AggregateType . UniqueCount => await filteredQuery . Distinct ( ) . CountAsync ( cancellationToken ) ,
129+ AggregateType . Sum => await filteredQuery . SumAsync ( x => ( decimal ) x , cancellationToken ) ,
130+ AggregateType . Average => await filteredQuery . AverageAsync ( x => ( decimal ) x , cancellationToken ) ,
131+ AggregateType . Min => await filteredQuery . MinAsync ( cancellationToken ) ,
132+ AggregateType . Max => await filteredQuery . MaxAsync ( cancellationToken ) ,
122133 _ => throw new NotImplementedException ( ) ,
123134 } ;
124135 }
125136
126137 public static IEnumerable < MappingModel > GetMappings < TEntity > ( )
127138 {
128- var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as GridifyMapper < TEntity > ;
139+ var mapper = EntityGridifyMapperByType [ typeof ( TEntity ) ] as FilterMapper < TEntity > ;
129140
130141 return mapper ! . GetCurrentMaps ( ) . Select ( x => new MappingModel
131142 {
@@ -138,4 +149,13 @@ public static IEnumerable<MappingModel> GetMappings<TEntity>()
138149 : x . To . Body . Type . Name ,
139150 } ) ;
140151 }
152+
153+ private static Expression < Func < T , object > > CreateSelector < T > ( string propertyName )
154+ {
155+ var parameter = Expression . Parameter ( typeof ( T ) , "x" ) ;
156+ var property = Expression . Property ( parameter , propertyName ) ;
157+ var converted = Expression . Convert ( property , typeof ( object ) ) ;
158+
159+ return Expression . Lambda < Func < T , object > > ( converted , parameter ) ;
160+ }
141161}
0 commit comments