private Expression TranslateGroupingKey(Expression expression) { switch (expression) { case NewExpression newExpression: if (newExpression.Arguments.Count == 0) { return(newExpression); } var newArguments = new Expression[newExpression.Arguments.Count]; for (var i = 0; i < newArguments.Length; i++) { newArguments[i] = TranslateGroupingKey(newExpression.Arguments[i]); if (newArguments[i] == null) { return(null); } } return(newExpression.Update(newArguments)); case MemberInitExpression memberInitExpression: var updatedNewExpression = (NewExpression)TranslateGroupingKey(memberInitExpression.NewExpression); if (updatedNewExpression == null) { return(null); } var newBindings = new MemberAssignment[memberInitExpression.Bindings.Count]; for (var i = 0; i < newBindings.Length; i++) { var memberAssignment = (MemberAssignment)memberInitExpression.Bindings[i]; var visitedExpression = TranslateGroupingKey(memberAssignment.Expression); if (visitedExpression == null) { return(null); } newBindings[i] = memberAssignment.Update(visitedExpression); } return(memberInitExpression.Update(updatedNewExpression, newBindings)); default: var translation = _expressionTranslator.Translate(expression); if (translation == null) { return(null); } return(translation.Type == expression.Type ? (Expression)translation : Expression.Convert(translation, expression.Type)); } }
public override Expression Visit(Expression expression) { if (expression == null) { return(null); } if (!(expression is NewExpression || expression is MemberInitExpression || expression is EntityShaperExpression || expression is IncludeExpression)) { // This skips the group parameter from GroupJoin if (expression is ParameterExpression parameter && parameter.Type.IsGenericType && parameter.Type.GetGenericTypeDefinition() == typeof(IEnumerable <>)) { return(parameter); } if (_clientEval) { switch (expression) { case ConstantExpression _: return(expression); case MaterializeCollectionNavigationExpression materializeCollectionNavigationExpression: return(AddCollectionProjection( _queryableMethodTranslatingExpressionVisitor.TranslateSubquery( materializeCollectionNavigationExpression.Subquery), materializeCollectionNavigationExpression.Navigation, null)); case MethodCallExpression methodCallExpression: { if (methodCallExpression.Method.IsGenericMethod && methodCallExpression.Method.DeclaringType == typeof(Enumerable) && methodCallExpression.Method.Name == nameof(Enumerable.ToList)) { return(AddCollectionProjection( _queryableMethodTranslatingExpressionVisitor.TranslateSubquery( methodCallExpression.Arguments[0]), null, methodCallExpression.Method.GetGenericArguments()[0])); } var subquery = _queryableMethodTranslatingExpressionVisitor.TranslateSubquery(methodCallExpression); if (subquery != null) { if (subquery.ResultCardinality == ResultCardinality.Enumerable) { return(AddCollectionProjection(subquery, null, subquery.ShaperExpression.Type)); } return(new SingleResultShaperExpression( new ProjectionBindingExpression( _queryExpression, _queryExpression.AddSubqueryProjection(subquery, out var innerShaper), typeof(ValueBuffer)), innerShaper, subquery.ShaperExpression.Type)); } break; } } var translation = _expressionTranslatingExpressionVisitor.Translate(expression); if (translation == null) { return(base.Visit(expression)); } if (translation.Type != expression.Type) { translation = NullSafeConvert(translation, expression.Type); } return(new ProjectionBindingExpression(_queryExpression, _queryExpression.AddToProjection(translation), expression.Type)); } else { var translation = _expressionTranslatingExpressionVisitor.Translate(expression); if (translation == null) { return(null); } if (translation.Type != expression.Type) { translation = NullSafeConvert(translation, expression.Type); } _projectionMapping[_projectionMembers.Peek()] = translation; return(new ProjectionBindingExpression(_queryExpression, _projectionMembers.Peek(), expression.Type)); } } return(base.Visit(expression)); }