@@ -1343,26 +1343,41 @@ private Expression GetMember(Expression expression, MemberInfo member, Expressio
13431343 if ( memberIndex < 0 )
13441344 throw new InvalidOperationException ( string . Format ( Strings . ExCouldNotGetMemberXFromExpression , member ) ) ;
13451345 var argument = newExpression . Arguments [ memberIndex ] ;
1346- var currentLambda = state . CurrentLambda ;
1347- if ( ! ( currentLambda is null ) && context . Bindings . TryGetValue ( currentLambda . Parameters [ 0 ] , out var projection ) ) {
1348- // Here, we try to detect whether the expression has already visited, in such cases
1349- // re-visiting it may cause issues. For instance, .OrderBy(x=>x.SomeField) translation
1350- // gets projection of already visited source and substitutes parameter 'x' access with
1351- // that projection. For now TranslatorState.ShouldOmitConvertToObject == true, is a marker
1352- // of OrderBy visiting, because it is the only place that sets 'true' to the property,
1353- // but we can't rely on it for future-proof solution.
1354-
1355- // Knowing that parameter-to-projection binding happens when expression has visited,
1356- // we assume this check is enough for certain cases, probably not for all of them.
1357- // We can't deny visiting of the argument for all the cases because of chance to break
1358- // some cases we could not imagine at the time of changes
1359- switch ( argument . NodeType ) {
1360- case ExpressionType . TypeAs :
1361- case ExpressionType . Convert :
1362- case ExpressionType . ConvertChecked :
1363- if ( argument . Type == typeof ( object ) && state . ShouldOmitConvertToObject )
1364- argument = argument . StripCasts ( ) ;
1365- break ;
1346+
1347+ if ( state . GroupingKey || state . OrderingKey ) {
1348+ var requireVisit = ! argument . IsExtendedExpression ( ) && argument . NodeType switch {
1349+ ExpressionType . New => true ,
1350+ ExpressionType . Call => true ,
1351+ ExpressionType . Coalesce => true ,
1352+ ExpressionType . Conditional => true ,
1353+ _ => false
1354+ } ;
1355+
1356+ var currentLambda = state . CurrentLambda ;
1357+ if ( ! ( currentLambda is null ) && context . Bindings . TryGetValue ( currentLambda . Parameters [ 0 ] , out var projection )
1358+ && ! requireVisit ) {
1359+ // Here, we try to detect whether the expression has already visited, in such cases
1360+ // re-visiting it may cause issues. For instance, .OrderBy(x=>x.SomeField) translation
1361+ // gets projection of already visited source and substitutes parameter 'x' access with
1362+ // that projection. For now TranslatorState.ShouldOmitConvertToObject == true, is a marker
1363+ // of OrderBy visiting, because it is the only place that sets 'true' to the property,
1364+ // but we can't rely on it for future-proof solution.
1365+
1366+ // Knowing that parameter-to-projection binding happens when expression has visited,
1367+ // we assume this check is enough for certain cases, probably not for all of them.
1368+ // We can't deny visiting of the argument for all the cases because of chance to break
1369+ // some cases we could not imagine at the time of changes
1370+ switch ( argument . NodeType ) {
1371+ case ExpressionType . TypeAs :
1372+ case ExpressionType . Convert :
1373+ case ExpressionType . ConvertChecked :
1374+ if ( argument . Type == typeof ( object ) && state . ShouldOmitConvertToObject )
1375+ argument = argument . StripCasts ( ) ;
1376+ break ;
1377+ }
1378+ }
1379+ else {
1380+ argument = Visit ( argument ) ;
13661381 }
13671382 }
13681383 else {
0 commit comments