@@ -253,7 +253,7 @@ private static Expression WrapIntoSelectFromGrouping(ParameterExpression paramet
253253
254254 Expression selectExpression ;
255255 if ( QueryableHelpers . IsGenericEnumerable ( innerSelectType ) && selectCollectionHandling == SelectCollectionHandling . Flatten )
256- selectExpression = Expression . Call ( typeof ( Enumerable ) , "SelectMany" , new Type [ ] { selectType , innerSelectType . GenericTypeArguments . First ( ) } , parameter , innerLambdaExpression ) ;
256+ selectExpression = Expression . Call ( typeof ( Enumerable ) , "SelectMany" , new Type [ ] { selectType , QueryableHelpers . GetTypeOfEnumerable ( innerSelectType , true ) } , parameter , innerLambdaExpression ) ;
257257 else
258258 selectExpression = Expression . Call ( typeof ( Enumerable ) , "Select" , new Type [ ] { selectType , innerSelectType } , parameter , innerLambdaExpression ) ;
259259
@@ -359,7 +359,7 @@ internal static Expression InternalResolvePathExpression(int step, Expression pa
359359 else
360360 {
361361 // enumerable.
362- var listGenericArgumentType = memberExpression . Type . GetGenericArguments ( ) . First ( ) ;
362+ var listGenericArgumentType = QueryableHelpers . GetTypeOfEnumerable ( memberExpression . Type , true ) ;
363363
364364 // sub param.
365365 var innerParam = Expression . Parameter ( listGenericArgumentType ) ;
@@ -432,7 +432,7 @@ public static ConstantExpression ResolveConstant(Expression member, object value
432432 public static IQueryable CreateOrderByExpression ( IQueryable query , string path , QueryOrderByDirection direction , bool append = true )
433433 {
434434 var parameter = Expression . Parameter ( query . ElementType , "t" ) ;
435- var member = QueryableHelpers . ResolvePathForExpression ( parameter , path ) ;
435+ var member = QueryableHelpers . ResolvePathForExpression ( parameter , path , false ) ;
436436
437437 string sortCommand = null ;
438438 if ( direction == QueryOrderByDirection . Descending )
@@ -503,7 +503,7 @@ internal static Expression InternalCreateConditionExpression(int recursionStep,
503503
504504 if ( IsGenericEnumerable ( memberExpression ) )
505505 {
506- var listGenericArgumentType = memberExpression . Type . GetGenericArguments ( ) . First ( ) ;
506+ var listGenericArgumentType = QueryableHelpers . GetTypeOfEnumerable ( memberExpression . Type , true ) ;
507507 var innerParameter = Expression . Parameter ( listGenericArgumentType , $ "t{ ++ recursionStep } ") ;
508508 var innerLambda = InternalCreateConditionExpression ( recursionStep , listGenericArgumentType , innerParameter , innerParameter , parts . Skip ( 1 ) . ToList ( ) , condition , value , convertStrategy , collectionHandling , nullChecking , stringComparison , negate ) ;
509509
@@ -623,12 +623,43 @@ public static Expression CreateConditionExpression(Type type,
623623 public static bool IsGenericEnumerable ( Expression member ) => IsGenericEnumerable ( member . Type ) ;
624624 public static bool IsGenericEnumerable ( Type type )
625625 {
626- if ( ! type . IsGenericType )
626+ if ( type == typeof ( string ) )
627627 return false ;
628628
629- var genericArgumentType = type . GenericTypeArguments . First ( ) ;
630- var ret = typeof ( IEnumerable < > ) . MakeGenericType ( genericArgumentType ) . IsAssignableFrom ( type ) ;
631- return ret ;
629+ if ( type . IsGenericType )
630+ {
631+ var makeGenericType = typeof ( IEnumerable < > ) . MakeGenericType ( type . GetGenericArguments ( ) [ 0 ] ) ;
632+ var possible = makeGenericType . IsAssignableFrom ( type ) ;
633+ if ( possible )
634+ return true ;
635+ }
636+
637+ var result = type . GetInterfaces ( ) . Any ( t => t . IsGenericType && t . GetGenericTypeDefinition ( ) == typeof ( IEnumerable < > ) ) ;
638+ return result ;
639+ }
640+
641+ public static Type GetTypeOfEnumerable ( Type genericEnumerableType , bool throwIfNotEnumerable )
642+ {
643+ Type result = null ;
644+
645+ if ( genericEnumerableType . IsGenericType )
646+ {
647+ var makeGenericType = typeof ( IEnumerable < > ) . MakeGenericType ( genericEnumerableType . GetGenericArguments ( ) [ 0 ] ) ;
648+ var possible = makeGenericType . IsAssignableFrom ( genericEnumerableType ) ;
649+ if ( possible )
650+ return genericEnumerableType . GetGenericArguments ( ) [ 0 ] ;
651+ }
652+
653+ result = genericEnumerableType . GetInterfaces ( ) . FirstOrDefault ( t => t . IsGenericType && t . GetGenericTypeDefinition ( ) == typeof ( IEnumerable < > ) ) ;
654+ if ( result == null )
655+ {
656+ if ( throwIfNotEnumerable )
657+ throw new Exception ( "Not a IEnumerable<T>" ) ;
658+
659+ return null ;
660+ }
661+
662+ return result . GetGenericArguments ( ) . First ( ) ;
632663 }
633664 }
634665}
0 commit comments