protected override Expression VisitMemberExpression (MemberExpression expression)
{
ArgumentUtility.CheckNotNull ("expression", expression);
var newInnerExpression = VisitExpression (expression.Expression);
var innerExpressionAsSqlCaseExpression = newInnerExpression as SqlCaseExpression;
if (innerExpressionAsSqlCaseExpression != null)
{
var originalCases = innerExpressionAsSqlCaseExpression.Cases;
var originalElseCase = innerExpressionAsSqlCaseExpression.ElseCase;
var newCases = originalCases.Select (c => new SqlCaseExpression.CaseWhenPair (c.When, Expression.MakeMemberAccess (c.Then, expression.Member)));
var newElseCase = originalElseCase != null ? Expression.MakeMemberAccess (originalElseCase, expression.Member) : null;
// If there is no else case, ensure that the resulting type is nullable
var caseExpressionType =
newElseCase == null && expression.Type.IsValueType && Nullable.GetUnderlyingType (expression.Type) == null
? typeof (Nullable<>).MakeGenericType (expression.Type)
: expression.Type;
var newSqlCaseExpression = new SqlCaseExpression (caseExpressionType, newCases, newElseCase);
return VisitExpression (newSqlCaseExpression);
}
if (newInnerExpression.NodeType == ExpressionType.Coalesce)
{
var innerExpressionAsBinaryExpression = (BinaryExpression) newInnerExpression;
var newConditionalExpression = Expression.Condition (
new SqlIsNotNullExpression (innerExpressionAsBinaryExpression.Left),
Expression.MakeMemberAccess (innerExpressionAsBinaryExpression.Left, expression.Member),
Expression.MakeMemberAccess (innerExpressionAsBinaryExpression.Right, expression.Member));
return VisitExpression (newConditionalExpression);
}
var innerExpressionAsSqlSubStatementExpression = newInnerExpression as SqlSubStatementExpression;
if (innerExpressionAsSqlSubStatementExpression != null)
{
var sqlStatementBuilder = new SqlStatementBuilder (innerExpressionAsSqlSubStatementExpression.SqlStatement);
var namedExpression = (NamedExpression) sqlStatementBuilder.SelectProjection;
sqlStatementBuilder.SelectProjection = new NamedExpression (
namedExpression.Name, VisitExpression (Expression.MakeMemberAccess (namedExpression.Expression, expression.Member)));
sqlStatementBuilder.RecalculateDataInfo (innerExpressionAsSqlSubStatementExpression.SqlStatement.SelectProjection);
return new SqlSubStatementExpression (sqlStatementBuilder.GetSqlStatement());
}
var memberAsPropertyInfo = expression.Member as PropertyInfo;
if (memberAsPropertyInfo != null)
{
var methodInfo = memberAsPropertyInfo.GetGetMethod();
if (methodInfo != null)
{
var methodCallExpression = Expression.Call (expression.Expression, methodInfo);
var tranformer = _methodCallTransformerProvider.GetTransformer(methodCallExpression);
if (tranformer != null)
{
var tranformedExpression = tranformer.Transform (methodCallExpression);
return VisitExpression (tranformedExpression);
}
}
}
return base.VisitMemberExpression (expression);
}