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);
        }
Example #2
0
        /// <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);
        }