示例#1
0
        /// <summary>
        /// Convierte un <see cref="MemberExpression"/> a SQL, tomando en cuenta los aliases de la lista de froms
        /// y la lógica descrita en <see cref="SqlExprParams"/>
        /// </summary>
        static string SingleMemberToSql(SqlExprParams pars, string baseMemberName, string subpath, MemberExpression mem)
        {
            var memberName = baseMemberName + subpath;

            if (pars.FromListNamed)
            {
                //Si la lista de FROM tiene aliases, el parametro del select no hace referencia a una tabla,
                //si no a un objeto de aliases donde cada propiedad es una tabla o un elemento de un JOIN
                MemberExpression firstExpr = mem;
                while (firstExpr is MemberExpression sm1 && sm1.Expression is MemberExpression sm2)
                {
                    firstExpr = sm2;
                }

                if (IsFromParam(mem.Expression))
                {
                    throw new ArgumentException("No esta soportado obtener una expresión de * en el SingleMemberSql");
                }
                else if (IsFromParam(firstExpr.Expression))
                {
                    return(TableRefToSql(firstExpr.Member.Name, memberName));
                }
                else if (IsRawTableRef(firstExpr.Expression, out var raw))
                {
                    return(RawTableRefToSql(raw, SqlSelect.ColNameToStr(memberName)));
                }
            }
            else
            {
                //Si la lista de FROM no tiene aliases, el parámetro del SELECT hace referencia a la tabla del SELECT

                Expression firstExpr = mem;
                while (firstExpr is MemberExpression sm)
                {
                    firstExpr = sm.Expression;
                }

                if (IsFromParam(firstExpr))
                {
                    return(TableRefToSql(pars.FromListAlias, memberName));
                }
                else if (IsRawTableRef(firstExpr, out var raw))
                {
                    return(RawTableRefToSql(raw, SqlSelect.ColNameToStr(memberName)));
                }
            }

            //Intentamos convertir al Expr a string con el replace:
            var exprRep = SqlFromList.ReplaceStringAliasMembers(mem.Expression, pars.Replace);

            if (exprRep != null)
            {
                return($"{exprRep}.\"{memberName}\"");
            }

            var exprStr = ExprToSql(mem.Expression, pars, false);

            return($"{exprStr}.\"{memberName}\"");
        }
示例#2
0
        /// <summary>
        /// Convierte una expresión a SQL
        /// </summary>
        public static (IReadOnlyList <SqlSubpath> sql, bool star) ExprToSqlStar(Expression expr, SqlExprParams pars, bool rewrite)
        {
            if (rewrite)
            {
                var visitor = new SqlRewriteVisitor(pars);
                expr = visitor.Visit(expr);
            }
            //Es importante primero comprobar la igualdad del parametro, ya que el replace list tiene una entrada para el parametro tambien
            if (IsFromParam(expr))
            {
                if (pars.FromListNamed)
                {
                    return(SqlSubpath.FromString($"*"), true);
                }

                return(SqlSubpath.FromString(SqlExpression.TableRefToSql(pars.FromListAlias, "*")), true);
            }

            var replace = SqlFromList.ReplaceStringAliasMembers(expr, pars.Replace);

            if (replace != null)
            {
                return(SqlSubpath.FromString(replace), false);
            }

            if (expr is MemberExpression mem)
            {
                return(MemberToSql(mem, pars));
            }
            else if (expr is ConditionalExpression cond)
            {
                return(SqlSubpath.FromString(ConditionalToSql(cond, pars)), false);
            }
            else if (expr is MethodCallExpression call)
            {
                return(SqlSubpath.FromString(CallToSql(call, pars)), false);
            }
            else if (expr is MemberInitExpression || expr is NewExpression)
            {
                //TODO: Note la similaridad de este código, del InsertToString y del SelectStr
                //Puede ser que estas 3 funciones sean lógicamente equivalentes y que se puedan unificar

                var exprs = SqlSelect
                            .ExtractInitExpr(expr)
                            .Select(x => (x.mem, sql: ExprToSqlStar(x.expr, pars, false)));
                ;

                if (exprs.Any(y => y.sql.star))
                {
                    throw new ArgumentException("No esta soportado una expresión star '*' en una subexpresión");
                }

                var subpaths = exprs
                               .SelectMany(x => x.sql.sql, (parent, child) => (member: parent.mem, subpath: child))
                               .Select(x => new SqlSubpath(x.subpath.Sql, "_" + x.member.Name + x.subpath.Subpath))
                               .ToList()
                ;

                return(subpaths, false);
            }
            throw new ArgumentException("No se pudo convertir a SQL la expresión " + expr.ToString());
        }