public JoinExpression VisitJoin(MethodCallExpression expression) { // Handle the default Queryable extension Join if (IsDeclaring(expression, typeof(Queryable), typeof(Enumerable))) { // Resolve the sources ASourceExpression outer = Visit <ASourceExpression>(expression.Arguments[0]); ASourceExpression inner = Visit <ASourceExpression>(expression.Arguments[1]); // Set the active expressions (so fields calls can find their expression) sources = new[] { outer, inner }; // Create the predicate LambdaExpression outerLambda = (LambdaExpression)StripQuotes(expression.Arguments[2]); LambdaExpression innerLambda = (LambdaExpression)StripQuotes(expression.Arguments[3]); FieldExpression outerField = Visit <FieldExpression>(outerLambda.Body); FieldExpression innerField = Visit <FieldExpression>(innerLambda.Body); APredicateExpression predicate = new CompositeExpression(outerField, innerField, CompositeOperator.Equal); // Decode the result selector IEnumerable <FieldExpression> fields = DecodeJoinSelector(expression.Arguments[4], outer.Fields, inner.Fields); // Create the expression return(new JoinExpression(outer, inner, predicate, fields, JoinType.Inner)); } // Handle the default SqlQueryableHelper extension Join if (IsDeclaring(expression, typeof(SqlQueryableHelper))) { // Resolve the sources ASourceExpression outer = Visit <ASourceExpression>(expression.Arguments[0]); ASourceExpression inner = Visit <ASourceExpression>(expression.Arguments[1]); // Set the active expressions (so fields calls can find their expression) sources = new[] { outer, inner }; // Create the predicate LambdaExpression predicateLambda = (LambdaExpression)StripQuotes(expression.Arguments[2]); APredicateExpression predicate = Visit <APredicateExpression>(predicateLambda.Body); // Decode the result selector IEnumerable <FieldExpression> fields = DecodeJoinSelector(expression.Arguments[3], outer.Fields, inner.Fields); // Resolve the join type ConstantExpression joinType = (ConstantExpression)expression.Arguments[4]; // Create the expression return(new JoinExpression(outer, inner, predicate, fields, (JoinType)joinType.Value)); } throw new MethodTranslationException(expression.Method); }
/// <summary> /// Visits the specified expression. /// </summary> /// <param name="expression">The expression to visit.</param> public virtual Expression VisitComposite(CompositeExpression expression) { if (expression == null) { throw new ArgumentNullException(nameof(expression)); } Builder.Append("("); Visit(expression.Left); if (expression.Operator == CompositeOperator.And) { Builder.Append(" and "); } else if (expression.Operator == CompositeOperator.Or) { Builder.Append(" or "); } else if (expression.Operator == CompositeOperator.GreaterThan) { Builder.Append(" > "); } else if (expression.Operator == CompositeOperator.GreaterThanOrEqual) { Builder.Append(" >= "); } else if (expression.Operator == CompositeOperator.LessThan) { Builder.Append(" < "); } else if (expression.Operator == CompositeOperator.LessThanOrEqual) { Builder.Append(" <= "); } else if (expression.Operator == CompositeOperator.Equal) { if (expression.Right is NullExpression) { Builder.Append(" is "); } else { Builder.Append(" = "); } } else if (expression.Operator == CompositeOperator.NotEqual) { if (expression.Right is NullExpression) { Builder.Append(" is not "); } else { Builder.Append(" <> "); } } else { throw new NotSupportedException($"Cannot generate sql for '{expression.Operator}' operator of {nameof(CompositeExpression)}."); } Visit(expression.Right); Builder.Append(")"); return(expression); }