public Expression VisitSqlGroupingSelect(SqlGroupingSelectExpression expression) { var newKeyExpression = ApplyValueContext(expression.KeyExpression); var newElementExpression = ApplyValueContext(expression.ElementExpression); var newAggregationExpressions = expression.AggregationExpressions .Select(ApplyValueContext) .ToArray(); if (newKeyExpression != expression.KeyExpression || newElementExpression != expression.ElementExpression || !newAggregationExpressions.SequenceEqual(expression.AggregationExpressions)) { return(_context.UpdateGroupingSelectAndAddMapping(expression, newKeyExpression, newElementExpression, newAggregationExpressions)); } return(expression); }
public Expression ProcessNames(NamedExpression outerExpression) { ArgumentUtility.CheckNotNull("outerExpression", outerExpression); // We cannot implement this as an expression visitor because expression visitors have no fallback case, i.e., there is no good possibility // to catch all cases not explicitly handled by a visitor. We need that catch-all case, however, and don't want to automatically visit the // expressions' children. if (outerExpression.Expression is NewExpression) { var newExpression = (NewExpression)outerExpression.Expression; var preparedArguments = newExpression.Arguments.Select(expr => ProcessNames(new NamedExpression(outerExpression.Name, expr))); if (newExpression.Members != null && newExpression.Members.Count > 0) { return(Expression.New(newExpression.Constructor, preparedArguments, newExpression.Members)); } else { return(Expression.New(newExpression.Constructor, preparedArguments)); } } else if (outerExpression.Expression is MethodCallExpression) { var methodCallExpression = (MethodCallExpression)outerExpression.Expression; var namedInstance = methodCallExpression.Object != null ? new NamedExpression(outerExpression.Name, methodCallExpression.Object) : null; var namedArguments = methodCallExpression.Arguments.Select((a, i) => new NamedExpression(outerExpression.Name, a)); return(Expression.Call( namedInstance != null ? ProcessNames(namedInstance) : null, methodCallExpression.Method, namedArguments.Select(ProcessNames))); } else if (outerExpression.Expression is SqlEntityExpression) { var entityExpression = (SqlEntityExpression)outerExpression.Expression; string newName = CombineNames(outerExpression.Name, entityExpression.Name); return(_mappingResolutionContext.UpdateEntityAndAddMapping(entityExpression, entityExpression.Type, entityExpression.TableAlias, newName)); } else if (outerExpression.Expression is NamedExpression) { var namedExpression = (NamedExpression)outerExpression.Expression; var newName = CombineNames(outerExpression.Name, namedExpression.Name); return(ProcessNames(new NamedExpression(newName, namedExpression.Expression))); } else if (outerExpression.Expression is SqlGroupingSelectExpression) { var groupingSelectExpression = (SqlGroupingSelectExpression)outerExpression.Expression; var newKeyExpression = ProcessNames(new NamedExpression(outerExpression.Name, groupingSelectExpression.KeyExpression)); var newElementExpression = ProcessNames(new NamedExpression(outerExpression.Name, groupingSelectExpression.ElementExpression)); var newAggregationExpressions = groupingSelectExpression.AggregationExpressions.Select(e => ProcessNames(new NamedExpression(outerExpression.Name, e))); return(_mappingResolutionContext.UpdateGroupingSelectAndAddMapping( groupingSelectExpression, newKeyExpression, newElementExpression, newAggregationExpressions)); } else if (outerExpression.Expression.NodeType == ExpressionType.Convert || outerExpression.Expression.NodeType == ExpressionType.ConvertChecked) { var unaryExpression = (UnaryExpression)outerExpression.Expression; var innerNamedExpression = new NamedExpression(outerExpression.Name, unaryExpression.Operand); return(Expression.MakeUnary( unaryExpression.NodeType, ProcessNames(innerNamedExpression), unaryExpression.Type, unaryExpression.Method)); } else { return(outerExpression); } }