static IBuildContext BuildCteContext(ExpressionBuilder builder, BuildInfo buildInfo)
        {
            var methodCall = (MethodCallExpression)buildInfo.Expression;

            Expression bodyExpr;
            IQueryable query       = null;
            string     name        = null;
            bool       isRecursive = false;

            switch (methodCall.Arguments.Count)
            {
            case 1:
                bodyExpr = methodCall.Arguments[0].Unwrap();
                break;

            case 2:
                bodyExpr = methodCall.Arguments[0].Unwrap();
                name     = methodCall.Arguments[1].EvaluateExpression() as string;
                break;

            case 3:
                query       = methodCall.Arguments[0].EvaluateExpression() as IQueryable;
                bodyExpr    = methodCall.Arguments[1].Unwrap();
                name        = methodCall.Arguments[2].EvaluateExpression() as string;
                isRecursive = true;
                break;

            default:
                throw new InvalidOperationException();
            }

            builder.RegisterCte(query, bodyExpr, () => new CteClause(null, bodyExpr.Type.GetGenericArgumentsEx()[0], isRecursive, name));

            var cte = builder.BuildCte(bodyExpr,
                                       cteClause =>
            {
                var info     = new BuildInfo(buildInfo, bodyExpr, new SelectQuery());
                var sequence = builder.BuildSequence(info);

                if (cteClause == null)
                {
                    cteClause = new CteClause(sequence.SelectQuery, bodyExpr.Type.GetGenericArgumentsEx()[0], isRecursive, name);
                }
                else
                {
                    cteClause.Body = sequence.SelectQuery;
                    cteClause.Name = name;
                }

                return(Tuple.Create(cteClause, sequence));
            }
                                       );

            var cteBuildInfo = new BuildInfo(buildInfo, bodyExpr, buildInfo.SelectQuery);
            var cteContext   = new CteTableContext(builder, cteBuildInfo, cte.Item1, bodyExpr);

            return(cteContext);
        }
 public CteTableContext(ExpressionBuilder builder, BuildInfo buildInfo, CteClause cte, Expression cteExpression)
     : base(builder, buildInfo, new SqlCteTable(builder.MappingSchema, cte))
 {
     _cte           = cte;
     _cteExpression = cteExpression;
 }