/// <summary>
 /// 初始化 <see cref="NpgUpdateExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 public NpgUpdateExpressionVisitor(AliasGenerator ag, ISqlBuilder builder)
     : base(ag, builder)
 {
     _ag           = ag;
     _builder      = builder;
     _visitedStack = base.VisitedStack;
 }
示例#2
0
 /// <summary>
 /// 初始化 <see cref="OrderByExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 /// <param name="groupBy">GROUP BY 子句</param>
 /// <param name="alias">指定的表别名</param>
 public OrderByExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbExpression groupBy, string alias)
     : base(ag, builder)
 {
     _ag      = ag;
     _alias   = alias;
     _builder = builder;
     _groupBy = groupBy;
 }
 /// <summary>
 /// 初始化 <see cref="SQLiteUpdateExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 /// <param name="tree">更新语义</param>
 /// <param name="alias">指定的表达式别名</param>
 internal SQLiteUpdateExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbQueryUpdateTree tree, string alias)
     : base(ag, builder)
 {
     _tree         = tree;
     _alias        = alias;
     _builder      = builder;
     _visitedStack = base.VisitedStack;
 }
 /// <summary>
 /// 初始化 <see cref="WhereExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 public WhereExpressionVisitor(AliasGenerator ag, ISqlBuilder builder)
     : base(ag, builder)
 {
     _builder  = builder;
     _provider = _builder.Provider;
     _constor  = ((DbQueryProvider)_provider).Constor;
     _context  = _builder.TranslateContext;
 }
示例#5
0
        private static string GetTableAliasKey(Expression node)
        {
            if (node == null)
            {
                return(null);
            }

            //System.Console.WriteLine(exp);

            Expression exp = node.ReduceUnary();

            // 常量表达式 c
            if (exp.CanEvaluate())
            {
                return(null);
            }

            //  p
            var parameterExpression = exp as ParameterExpression;

            if (parameterExpression != null)
            {
                return(parameterExpression.Name);
            }

            // a=>a.Id
            var lambdaExpression = exp as LambdaExpression;

            if (lambdaExpression != null)
            {
                if (lambdaExpression.Parameters != null && lambdaExpression.Parameters.Count == 1 && !ExpressionExtensions.IsAnonymous(lambdaExpression.Parameters[0]))
                {
                    return(AliasGenerator.GetTableAliasKey(lambdaExpression.Parameters[0]));
                }
                else
                {
                    exp = lambdaExpression.Body.ReduceUnary();
                }
            }

            // a.Id
            // t.a
            // t.t.a
            // t.a.Id
            var memberExpression = exp as MemberExpression;

            if (memberExpression == null)
            {
                return(AliasGenerator.GetTableAliasKey(exp));
            }

            if (memberExpression.Visitable())
            {
                return(AliasGenerator.GetTableAliasKey(memberExpression.Expression));
            }

            return(memberExpression.Member.Name);
        }
示例#6
0
        // 获取 CROSS JOIN 子句关联表的的别名
        private void PrepareCrossAlias(DbExpression dbExpression, AliasGenerator ag)
        {
            var lambda = dbExpression.Expressions[1] as LambdaExpression;

            for (int index = 0; index < lambda.Parameters.Count; ++index)
            {
                ag.GetTableAlias(lambda.Parameters[index]);
            }
        }
        /// <summary>
        /// 实例化 <see cref="SqlServerDbSelectCommand"/> 类的新实例
        /// </summary>
        /// <param name="context">解析SQL命令上下文</param>
        /// <param name="ag">表别名解析器</param>
        /// <param name="hasMany">是否包含一对多导航属性</param>
        public SqlServerDbSelectCommand(ITranslateContext context, AliasGenerator ag, bool hasMany)
            : base(context, ag, hasMany)
        {
            _ag = ag;

            var dc = context.DbContext;

            _isNoLock   = ((SqlServerDbContext)dc).NoLock;
            _withNoLock = ((SqlServerDbQueryProvider)dc.Provider).WidthNoLock;
        }
示例#8
0
 /// <summary>
 /// 初始化 <see cref="ColumnExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 /// <param name="tree">查询语义</param>
 public ColumnExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbQuerySelectTree tree)
     : base(ag, builder)
 {
     _ag              = ag;
     _builder         = builder;
     _groupBy         = tree.GroupBy;
     _includes        = tree.Includes;
     _selectedColumns = new ColumnDescriptorCollection();
     _visitedStack    = base.VisitedStack;
 }
示例#9
0
        /// <summary>
        /// 初始化 <see cref="SqlServerJoinExpressionVisitor"/> 类的新实例
        /// </summary>
        /// <param name="ag">表别名解析器</param>
        /// <param name="builder">SQL 语句生成器</param>
        public SqlServerJoinExpressionVisitor(AliasGenerator ag, ISqlBuilder builder)
            : base(ag, builder)
        {
            _ag      = ag;
            _builder = builder;

            var context = builder.TranslateContext.DbContext;

            _isNoLock   = ((SqlServerDbContext)context).NoLock;
            _withNoLock = ((SqlServerDbQueryProvider)context.Provider).WidthNoLock;
        }
示例#10
0
        /// <summary>
        /// 实例化 <see cref="DbSelectCommand"/> 类的新实例
        /// </summary>
        /// <param name="context">解析SQL命令上下文</param>
        /// <param name="ag">别名</param>
        /// <param name="hasMany">是否包含一对多导航属性</param>
        public DbSelectCommand(ITranslateContext context, AliasGenerator ag, bool hasMany)
            : base(string.Empty, context != null ? context.Parameters : null, System.Data.CommandType.Text)
        {
            _ag      = ag;
            _context = context;
            _hasMany = hasMany;

            var provider = (DbQueryProvider)_context.DbContext.Provider;

            _joinFragment  = provider.CreateSqlBuilder(context);
            _whereFragment = provider.CreateSqlBuilder(context);
        }
示例#11
0
        /// <summary>
        /// 根据指定表达式取表别名
        /// </summary>
        /// <param name="expression">表达式</param>
        /// <remarks>
        /// t=>t.Id
        /// t.Id
        /// </remarks>
        public string GetTableAlias(Expression expression)
        {
            // p=>p.p
            // p=>p.Id
            // p=>p.t.Id
            // p.Id
            // p.t.Id
            // p.t
            // <>h__TransparentIdentifier0.p.Id
            XFrameworkException.Check.NotNull(expression, "expression");
            string key = AliasGenerator.GetTableAliasKey(expression);

            return(this.GetTableAlias(key));
        }
        /// <summary>
        /// 实例化 <see cref="NpgDbSelectCommand" /> 的新实例
        /// </summary>
        /// <param name="context">解析SQL命令上下文</param>
        /// <param name="aliasGenerator">别名</param>
        /// <param name="dbExpressionType">表达式类型</param>
        /// <param name="hasMany">是否包含一对多导航属性</param>
        public NpgDbSelectCommand(ITranslateContext context, AliasGenerator aliasGenerator, DbExpressionType dbExpressionType, bool hasMany)
            : base(context, aliasGenerator, hasMany)
        {
            _aliasGenerator   = aliasGenerator;
            _onPhrase         = ((DbQueryProvider)context.Provider).CreateSqlBuilder(context);
            _dbExpressionType = dbExpressionType;

            if (_dbExpressionType == DbExpressionType.Delete)
            {
                _keywordName = "USING ";
            }
            else if (_dbExpressionType == DbExpressionType.Update)
            {
                _keywordName = "FROM ";
            }
            _pad = "".PadLeft(_keywordName.Length, ' ');
        }
        /// <summary>
        /// 初始化 <see cref="NpgJoinExpressionVisitor"/> 类的新实例
        /// </summary>
        /// <param name="ag">表别名解析器</param>
        /// <param name="builder">SQL 语句生成器</param>
        /// <param name="dbExpressionType">表达式类型</param>
        /// <param name="cmd">SQL 命令</param>
        public NpgJoinExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbExpressionType dbExpressionType, NpgDbSelectCommand cmd)
            : base(ag, builder)
        {
            _ag = ag;
            _dbExpressionType = dbExpressionType;
            _cmd = cmd;

            if (_dbExpressionType == DbExpressionType.Delete)
            {
                _keywordName = "USING ";
            }
            else if (_dbExpressionType == DbExpressionType.Update)
            {
                _keywordName = "FROM ";
            }
            _pad = "".PadLeft(_keywordName.Length, ' ');
        }
示例#14
0
        /// <summary>
        /// 生成关联子句所表示的别名列表
        /// </summary>
        /// <param name="tree">查询语义</param>
        /// <param name="prefix">表别名前缀</param>
        /// <returns></returns>
        protected AliasGenerator PrepareTableAlias(DbQuerySelectTree tree, string prefix)
        {
            var ag = new AliasGenerator((tree.Joins != null ? tree.Joins.Count : 0) + 1, prefix);

            for (int index = 0; index < (tree.Joins != null ? tree.Joins.Count : -1); index++)
            {
                DbExpression d = tree.Joins[index];
                // [INNER/LEFT JOIN]
                if (d.DbExpressionType == DbExpressionType.LeftOuterJoin || d.DbExpressionType == DbExpressionType.Join || d.DbExpressionType == DbExpressionType.RightOuterJoin)
                {
                    this.PrepareJoinAlias(d, ag);
                }
                else if (d.DbExpressionType == DbExpressionType.SelectMany)
                {
                    this.PrepareCrossAlias(d, ag);
                }
            }

            return(ag);
        }
示例#15
0
 /// <summary>
 /// 初始化 <see cref="OracleUpdateExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 public OracleUpdateExpressionVisitor(AliasGenerator ag, ISqlBuilder builder)
     : base(ag, builder)
 {
     _builder = builder;
 }
        /// <summary>
        /// 添加导航属性关联
        /// </summary>
        protected override void TanslateNavMember()
        {
            if (base.NavMembers == null || base.NavMembers.Count == 0)
            {
                return;
            }

            // 如果有一对多的导航属性,肯定会产生嵌套查询。那么内层查询别名肯定是t0,所以需要清掉
            if (this.HasMany)
            {
                _ag = new AliasGenerator(_ag.ReserveQty);
            }
            //开始产生LEFT JOIN 子句
            ISqlBuilder builder = this.JoinFragment;

            foreach (var nav in base.NavMembers)
            {
                string              key         = nav.Key;
                MemberExpression    m           = nav.Expression;
                TypeRuntimeInfo     typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(m.Expression.Type);
                ForeignKeyAttribute attribute   = typeRuntime.GetMemberAttribute <ForeignKeyAttribute>(m.Member.Name);

                string innerKey   = string.Empty;
                string outerKey   = key;
                string innerAlias = string.Empty;

                if (!m.Expression.Visitable())
                {
                    innerKey = m.Expression.NodeType == ExpressionType.Parameter
                        ? (m.Expression as ParameterExpression).Name
                        : (m.Expression as MemberExpression).Member.Name;
                }
                else
                {
                    MemberExpression mLeft = null;
                    if (m.Expression.NodeType == ExpressionType.MemberAccess)
                    {
                        mLeft = m.Expression as MemberExpression;
                    }
                    else if (m.Expression.NodeType == ExpressionType.Call)
                    {
                        mLeft = (m.Expression as MethodCallExpression).Object as MemberExpression;
                    }
                    string name = TypeRuntimeInfoCache.GetRuntimeInfo(mLeft.Type).TableFullName;
                    innerAlias = _ag.GetJoinTableAlias(name);

                    if (string.IsNullOrEmpty(innerAlias))
                    {
                        string keyLeft = mLeft.GetKeyWidthoutAnonymous();
                        if (base.NavMembers.Contains(keyLeft))
                        {
                            innerKey = keyLeft;
                        }
                        innerAlias = _ag.GetNavTableAlias(innerKey);
                    }
                }

                string alias1 = !string.IsNullOrEmpty(innerAlias) ? innerAlias : _ag.GetTableAlias(innerKey);
                string alias2 = _ag.GetNavTableAlias(outerKey);


                builder.AppendNewLine();
                builder.Append("LEFT JOIN ");
                Type type = m.Type;
                if (type.IsGenericType)
                {
                    type = type.GetGenericArguments()[0];
                }
                var typeRuntime2 = TypeRuntimeInfoCache.GetRuntimeInfo(type);
                builder.AppendTable(typeRuntime2.TableSchema, typeRuntime2.TableFullName, typeRuntime2.IsTemporary);
                builder.Append(" ");
                builder.Append(alias2);

                bool withNoLock = !typeRuntime2.IsTemporary && _isNoLock && !string.IsNullOrEmpty(_withNoLock);
                if (withNoLock)
                {
                    builder.Append(' ');
                    builder.Append(_withNoLock);
                }

                builder.Append(" ON ");
                for (int i = 0; i < attribute.InnerKeys.Length; i++)
                {
                    if (attribute.InnerKeys[i].StartsWith(AppConst.CONSTANT_FOREIGNKEY, StringComparison.Ordinal))
                    {
                        builder.Append(attribute.InnerKeys[i].Substring(7));
                    }
                    else
                    {
                        builder.Append(alias1);
                        builder.Append('.');
                        builder.AppendMember(attribute.InnerKeys[i]);
                    }

                    builder.Append(" = ");

                    if (attribute.OuterKeys[i].StartsWith(AppConst.CONSTANT_FOREIGNKEY, StringComparison.Ordinal))
                    {
                        builder.Append(attribute.OuterKeys[i].Substring(7));
                    }
                    else
                    {
                        builder.Append(alias2);
                        builder.Append('.');
                        builder.AppendMember(attribute.OuterKeys[i]);
                    }

                    if (i < attribute.InnerKeys.Length - 1)
                    {
                        builder.Append(" AND ");
                    }
                }

                if (nav.Predicate != null)
                {
                    string alias   = _ag.GetNavTableAlias(nav.Key);
                    var    visitor = new NavPredicateExpressionVisitor(_ag, builder, alias);
                    visitor.Visit(nav.Predicate);
                }
            }
        }
示例#17
0
 /// <summary>
 /// 初始化 <see cref="JoinExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 public JoinExpressionVisitor(AliasGenerator ag, ISqlBuilder builder)
     : base(ag, builder)
 {
     _ag      = ag;
     _builder = builder;
 }
示例#18
0
 /// <summary>
 /// 初始化 <see cref="NpgWhereExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 public NpgWhereExpressionVisitor(AliasGenerator ag, ISqlBuilder builder)
     : base(ag, builder)
 {
     _builder = builder;
 }
示例#19
0
        // 获取 LEFT JOIN / INNER JOIN 子句关联表的的别名
        private void PrepareJoinAlias(DbExpression dbExpression, AliasGenerator ag)
        {
            Type   type       = dbExpression.Expressions[0].Type.GetGenericArguments()[0];
            string name       = TypeRuntimeInfoCache.GetRuntimeInfo(type).TableFullName;
            string outerAlias = null;

            // on a.Name equals b.Name 或 on new{ Name = a.Name,Id=a.Id } equals new { Name = b.Name,Id=b.Id }
            var left  = dbExpression.Expressions[1] as LambdaExpression;
            var right = dbExpression.Expressions[2] as LambdaExpression;

            if (left.Body.NodeType == ExpressionType.New)
            {
                var body1 = left.Body as NewExpression;
                var body2 = right.Body as NewExpression;
                for (int index = 0; index < body1.Arguments.Count; ++index)
                {
                    ag.GetTableAlias(body1.Arguments[index]);
                }
                for (int index = 0; index < body2.Arguments.Count; ++index)
                {
                    string alias = ag.GetTableAlias(body2.Arguments[index]);
                    outerAlias = alias;
                    // 记录显示指定的LEFT JOIN 表别名
                    ag.AddJoinTableAlias(name, alias);
                }
            }
            else if (left.Body.NodeType == ExpressionType.MemberInit)
            {
                var body1 = left.Body as MemberInitExpression;
                var body2 = right.Body as MemberInitExpression;
                for (int index = 0; index < body1.Bindings.Count; ++index)
                {
                    ag.GetTableAlias((body1.Bindings[index] as MemberAssignment).Expression);
                }
                for (int index = 0; index < body2.Bindings.Count; ++index)
                {
                    string alias = ag.GetTableAlias((body2.Bindings[index] as MemberAssignment).Expression);
                    outerAlias = alias;
                    // 记录显示指定的LEFT JOIN 表别名
                    ag.AddJoinTableAlias(name, alias);
                }
            }
            else
            {
                ag.GetTableAlias(dbExpression.Expressions[1]);
                string alias = ag.GetTableAlias(dbExpression.Expressions[2]);
                outerAlias = alias;
                // 记录显示指定的LEFT JOIN 表别名
                ag.AddJoinTableAlias(name, alias);
            }

            // 由 GetTable 重载指定的导航属性表别名
            if (dbExpression.Expressions.Length > 4)
            {
                if (string.IsNullOrEmpty(outerAlias) || outerAlias == AliasGenerator.EMPTYNAME)
                {
                    var    lambda = dbExpression.Expressions[3] as LambdaExpression;
                    string alias  = ag.GetTableAlias(lambda.Parameters[1]);
                    outerAlias = alias;
                    // 记录显示指定的LEFT JOIN 表别名
                    ag.AddJoinTableAlias(name, alias);
                }

                var    member = (dbExpression.Expressions[4] as LambdaExpression).Body as MemberExpression;
                string keyId  = member.GetKeyWidthoutAnonymous();
                // 记录GetTable<,>(path)指定的表别名
                ag.AddGetTableAlias(keyId, outerAlias);
            }
        }
        /// <summary>
        /// 添加导航属性关联
        /// </summary>
        protected override void TanslateNavMember()
        {
            if (this.NavMembers == null || this.NavMembers.Count == 0)
            {
                return;
            }

            // 如果有一对多的导航属性,肯定会产生嵌套查询。那么内层查询别名肯定是t0,所以需要清掉
            if (this.HasMany)
            {
                _aliasGenerator = new AliasGenerator(_aliasGenerator.ReserveQty);
            }
            //开始产生 USING 子句
            ISqlBuilder jf    = this.JoinFragment;
            int         index = -1;

            // 未生成USING子句
            if (_aliasGenerator.ReserveQty <= 1)
            {
                jf.AppendNewLine();
                jf.Append(_keywordName);
            }
            else
            {
                jf.Append(',');
                jf.AppendNewLine();
            }

            foreach (var nav in this.NavMembers)
            {
                index++;
                string              key         = nav.Key;
                MemberExpression    m           = nav.Expression;
                TypeRuntimeInfo     typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(m.Expression.Type);
                ForeignKeyAttribute attribute   = typeRuntime.GetMemberAttribute <ForeignKeyAttribute>(m.Member.Name);

                string innerKey   = string.Empty;
                string outerKey   = key;
                string innerAlias = string.Empty;

                if (!m.Expression.Visitable())
                {
                    innerKey = m.Expression.NodeType == ExpressionType.Parameter
                        ? (m.Expression as ParameterExpression).Name
                        : (m.Expression as MemberExpression).Member.Name;
                }
                else
                {
                    MemberExpression mLeft = null;
                    if (m.Expression.NodeType == ExpressionType.MemberAccess)
                    {
                        mLeft = m.Expression as MemberExpression;
                    }
                    else if (m.Expression.NodeType == ExpressionType.Call)
                    {
                        mLeft = (m.Expression as MethodCallExpression).Object as MemberExpression;
                    }
                    string name = TypeRuntimeInfoCache.GetRuntimeInfo(mLeft.Type).TableFullName;
                    innerAlias = _aliasGenerator.GetJoinTableAlias(name);

                    if (string.IsNullOrEmpty(innerAlias))
                    {
                        string keyLeft = mLeft.GetKeyWidthoutAnonymous();
                        if (this.NavMembers.Contains(keyLeft))
                        {
                            innerKey = keyLeft;
                        }
                        innerAlias = _aliasGenerator.GetNavTableAlias(innerKey);
                    }
                }

                string alias1 = !string.IsNullOrEmpty(innerAlias) ? innerAlias : _aliasGenerator.GetTableAlias(innerKey);
                string alias2 = _aliasGenerator.GetNavTableAlias(outerKey);

                // 补充与USING字符串同等间距的空白
                if (_aliasGenerator.ReserveQty > 1 || index > 0)
                {
                    jf.Append(_pad);
                }

                Type type         = m.Type;
                var  typeRumtime2 = TypeRuntimeInfoCache.GetRuntimeInfo(type);
                if (type.IsGenericType)
                {
                    type = type.GetGenericArguments()[0];
                }
                jf.AppendTable(typeRumtime2.TableSchema, typeRumtime2.TableName, typeRumtime2.IsTemporary);
                jf.Append(' ');
                jf.Append(alias2);

                if (_onPhrase.Length > 0)
                {
                    _onPhrase.Append(" AND ");
                }
                for (int i = 0; i < attribute.InnerKeys.Length; i++)
                {
                    if (attribute.InnerKeys[i].StartsWith(AppConst.CONSTANT_FOREIGNKEY, StringComparison.Ordinal))
                    {
                        _onPhrase.Append(attribute.InnerKeys[i].Substring(7));
                    }
                    else
                    {
                        _onPhrase.Append(alias1);
                        _onPhrase.Append('.');
                        _onPhrase.AppendMember(attribute.InnerKeys[i]);
                    }

                    _onPhrase.Append(" = ");

                    if (attribute.OuterKeys[i].StartsWith(AppConst.CONSTANT_FOREIGNKEY, StringComparison.Ordinal))
                    {
                        _onPhrase.Append(attribute.OuterKeys[i].Substring(7));
                    }
                    else
                    {
                        _onPhrase.Append(alias2);
                        _onPhrase.Append('.');
                        _onPhrase.AppendMember(attribute.OuterKeys[i]);
                    }
                }

                if (nav.Predicate != null)
                {
                    string alias   = _aliasGenerator.GetNavTableAlias(nav.Key);
                    var    visitor = new NavPredicateExpressionVisitor(_aliasGenerator, _onPhrase, alias);
                    visitor.Visit(nav.Predicate);
                }

                if (index < this.NavMembers.Count - 1)
                {
                    jf.Append(',');
                    jf.AppendNewLine();
                }
            }
        }
示例#21
0
 /// <summary>
 /// 初始化 <see cref="GroupByExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 public GroupByExpressionVisitor(AliasGenerator ag, ISqlBuilder builder)
     : base(ag, builder)
 {
     _builder = builder;
 }
示例#22
0
 /// <summary>
 /// 初始化 <see cref="NavPredicateExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 /// <param name="alias">指定的表别名</param>
 public NavPredicateExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, string alias)
     : base(ag, builder)
 {
     _alias   = alias;
     _builder = builder;
 }
 /// <summary>
 /// 初始化 <see cref="OracleColumnExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 /// <param name="tree">查询语义</param>
 public OracleColumnExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbQuerySelectTree tree)
     : base(ag, builder, tree)
 {
     _tree    = tree;
     _builder = builder;
 }
 /// <summary>
 /// 初始化 <see cref="HavingExpressionVisitor"/> 类的新实例
 /// </summary>
 /// <param name="ag">表别名解析器</param>
 /// <param name="builder">SQL 语句生成器</param>
 /// <param name="groupBy">GROUP BY 子句</param>
 public HavingExpressionVisitor(AliasGenerator ag, ISqlBuilder builder, DbExpression groupBy)
     : base(ag, builder)
 {
     _groupBy = groupBy;
     _builder = builder;
 }