コード例 #1
0
        /// <summary>
        /// Convierte una lista de FROM a SQL.
        /// Devuelve si la lista de FROMs tiene aliases
        /// </summary>
        /// <param name="item">Elemento que representa ya sea a un FROM o a una lista de JOINS</param>
        /// <param name="toSql">Convierte una expresión a SQL</param>
        /// <param name="paramSql">Alias del parámetro en SQL</param>
        /// <returns></returns>
        static (string sql, bool named) JoinToStrAlias(IFromListItem item, Func<Expression, string> toSql, IReadOnlyList<ExprStrRawSql> replaceMembers, string paramSql, bool forceUpperAlias, ParamMode paramMode, SqlParamDic paramDic)
        {
            if (item is SqlJoin join)
            {
                var currentAlias = toSql(join.Map.Parameters[1]);
                var currentOnStr = toSql(join.On.Body);
                var leftParam = join.Map.Parameters[0];
                var leftAlias = ReplaceStringAliasMembers(leftParam, replaceMembers);
                var rightSubsNoRep = ReplaceSubqueryLambda(join.Right, leftParam, replaceMembers);

                //Visitar el lado derecho del JOIN:
                //TODO: Hacer una función para visitar a las expresiones de lado derecho del JOIN

                var rightSubs = SqlRewriteVisitor.VisitFromItem(rightSubsNoRep);

                var rightFunc = Expression.Lambda(rightSubs).Compile();
                var rightExec = (IFromListItemTarget)rightFunc.DynamicInvoke(new object[0]);

                var latStr = join.Lateral ? "LATERAL " : "";
                var typeStr =
                    join.Type == JoinType.Inner ? "" :
                    join.Type == JoinType.Left ? "LEFT " :
                    join.Type == JoinType.Right ? "RIGHT " :
                    join.Type == JoinType.Outter ? "OUTTER " :
                    join.Type == JoinType.Cross ? "CROSS " :
                    throw new ArgumentException("Join type " + join.Type + " invalido");

                var right = $"{typeStr}JOIN {latStr}{SubqueryParenthesis(StatementStr.StatementToString(rightExec, paramMode, paramDic))} {currentAlias} ON {currentOnStr}";

                var leftStr = JoinToStrAlias(join.Left, toSql, replaceMembers, leftAlias, true, paramMode, paramDic);
                return (leftStr.sql + Environment.NewLine + right, true);
            }
            else if (item is ISqlFrom from)
            {
                var fromIt = StatementStr.StatementToString(from.Target, paramMode, paramDic);
                return ($"FROM {SubqueryParenthesis(fromIt)} {(((fromIt is QueryToStrResult) || forceUpperAlias) ? paramSql : "")}", false);
            }
            else if (item is FromListAlias alias)
            {
                return JoinToStrAlias(alias.From, toSql, replaceMembers, paramSql, forceUpperAlias, paramMode, paramDic);
            }

            throw new ArgumentException("El from-item debe de ser un JOIN, FROM o Alias()");
        }
コード例 #2
0
        /// <summary>
        /// Converts an UNION clause to string
        /// </summary>
        static string UnionToStr(UnionClause clause, SqlExprParams pars)
        {
            var b       = new StringBuilder();
            var typeStr =
                clause.Type == UnionType.Union ?
                (
                    clause.Uniqueness == UnionUniqueness.All ?
                    "UNION ALL" : "UNION"
                ) :
                clause.Type == UnionType.Intersect ? "INTERSECT" :
                clause.Type == UnionType.Except ? "EXCEPT" :
                throw new ArgumentException();

            var queryStr = StatementStr.QueryToStr(clause.Query, pars.ParamMode, pars.ParamDic);

            b.AppendLine(typeStr);
            b.AppendLine("(");
            b.AppendLine(TabStr(queryStr.Sql));
            b.Append(")");

            return(b.ToString());
        }