1- using System . Collections . Generic ;
1+ using System . ComponentModel . DataAnnotations ;
22using System . Globalization ;
33using System . Linq . Expressions ;
44using System . Reflection ;
@@ -34,13 +34,15 @@ public static object[] Run<TSource, TTarget>(this IQueryable<TSource> source, Qu
3434 return db is not null ? BuildQuery < TSource , TTarget > ( db , source , query , mapper ) . ToArray ( ) : Array . Empty < object > ( ) ;
3535 }
3636
37- public static MethodInfo ? GetGenericMethod ( Type executorType , int attributeCount , Type [ ] genericArgs )
37+ public static MethodInfo ? GetRunMethod ( Type executorType , Type [ ] genericArgs )
3838 {
39- var method = executorType
39+ return executorType
4040 . GetMethods ( BindingFlags . Static | BindingFlags . Public )
41- . FirstOrDefault ( m => m . CustomAttributes . Count ( ) == attributeCount ) ;
42-
43- return method ? . MakeGenericMethod ( genericArgs ) ;
41+ . FirstOrDefault ( m =>
42+ m . Name == "Run" &&
43+ m . IsGenericMethodDefinition &&
44+ m . GetGenericArguments ( ) . Length == genericArgs . Length )
45+ ? . MakeGenericMethod ( genericArgs ) ;
4446 }
4547
4648 private static IQueryable < object > BuildQuery < TSource , TTarget > ( DbContext db , IQueryable < TSource > source , Query ? query , IMapper ? mapper = null )
@@ -232,23 +234,19 @@ private static Expression BuildInExpression<T>(DbContext db, Query? query, Membe
232234
233235 private static IEnumerable < dynamic > RunSubquery ( DbContext db , Query ? query )
234236 {
235- var t = query ? . Entity . ToLower ( CultureInfo . InvariantCulture ) ?? string . Empty ;
236- var p = db . GetType ( ) . GetProperty ( t , BindingFlags . IgnoreCase | BindingFlags . Public | BindingFlags . Instance ) ?? throw new InvalidOperationException ( $ "Property '{ t } ' not found on type '{ db . GetType ( ) } '") ;
237+ var propName = query ? . Entity . ToLower ( CultureInfo . InvariantCulture ) ?? string . Empty ;
238+ var prop = db . GetType ( ) . GetProperty ( propName , BindingFlags . IgnoreCase | BindingFlags . Public | BindingFlags . Instance )
239+ ?? throw new InvalidOperationException ( $ "Property '{ propName } ' not found on type '{ db . GetType ( ) } '") ;
237240
238241 var methods = typeof ( QueryExecutor ) . GetMethods ( BindingFlags . Static | BindingFlags . Public ) ;
239242 var method = methods ? . FirstOrDefault ( m => m . CustomAttributes . Count ( ) == 1 ) ;
240- var dbSet = p . GetValue ( db ) ;
241- var genericType = p . PropertyType . GetGenericArguments ( ) . FirstOrDefault ( ) ;
242-
243- if ( dbSet != null && genericType != null )
244- {
243+ var dbSet = prop . GetValue ( db ) ?? throw new ValidationException ( $ "DbSet property '{ prop . Name } ' is null in DbContext.") ;
244+ var genericType = prop . PropertyType . GetGenericArguments ( ) . FirstOrDefault ( ) ?? throw new ValidationException ( $ "Missing DbSet generic type") ;
245245
246- var genericMethod = GetGenericMethod ( typeof ( QueryExecutor ) , 1 , [ genericType ] ) ;
246+ var genericMethod = GetRunMethod ( typeof ( QueryExecutor ) , [ genericType ] ) ;
247247
248- var queryable = dbSet ? . GetType ( ) . GetMethod ( "AsQueryable" ) ? . Invoke ( dbSet , null ) ;
249- return genericMethod ? . Invoke ( null , [ queryable , query ] ) as IEnumerable < dynamic > ?? Array . Empty < dynamic > ( ) ;
250- }
251- return Enumerable . Empty < dynamic > ( ) ;
248+ var queryable = dbSet ? . GetType ( ) . GetMethod ( "AsQueryable" ) ? . Invoke ( dbSet , null ) ;
249+ return genericMethod ? . Invoke ( null , [ queryable , query ] ) as IEnumerable < dynamic > ?? Array . Empty < dynamic > ( ) ;
252250 }
253251
254252 private static dynamic ? ProjectField ( object ? obj , string field )
@@ -269,10 +267,21 @@ private static Expression GetSearchValue(JsonValue? jsonVal, Type targetType)
269267
270268 if ( nonNullableType . IsEnum )
271269 {
272- var enumValue = jsonVal . Deserialize < string > ( ) ;
273- if ( enumValue != null )
270+ if ( valueKind == JsonValueKind . String )
271+ {
272+ var enumValue = jsonVal . Deserialize < string > ( ) ;
273+ if ( enumValue != null )
274+ {
275+ return Expression . Constant ( Enum . Parse ( nonNullableType , enumValue ) ) ;
276+ }
277+ }
278+ else if ( valueKind == JsonValueKind . Number )
274279 {
275- return Expression . Constant ( Enum . Parse ( nonNullableType , enumValue ) ) ;
280+ var enumValue = jsonVal . Deserialize < int ? > ( ) ;
281+ if ( enumValue != null )
282+ {
283+ return Expression . Constant ( Enum . ToObject ( nonNullableType , enumValue ) ) ;
284+ }
276285 }
277286 }
278287
0 commit comments