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;
}