Пример #1
0
        // Cross Join
        private void AppendCrossJoin(ISqlBuilder jf, DbExpression exp, TableAliasCache aliases)
        {
            if (!_appendedKeyword)
            {
                jf.AppendNewLine();
                jf.Append(_keywordName);
                _appendedKeyword = true;
            }
            else
            {
                jf.Append(',');
                jf.AppendNewLine();
                jf.Append("     ");
            }

            LambdaExpression lambdaExp = exp.Expressions[1] as LambdaExpression;
            Type             type      = lambdaExp.Parameters[1].Type;
            var typeRuntime            = TypeRuntimeInfoCache.GetRuntimeInfo(type);

            jf.Append(' ');
            jf.AppendMember(typeRuntime.TableName, !typeRuntime.IsTemporary);

            string alias = aliases.GetTableAlias(lambdaExp.Parameters[1]);

            jf.Append(' ');
            jf.Append(alias);
        }
Пример #2
0
 /// <summary>
 /// 初始化 <see cref="JoinExpressionVisitor"/> 类的新实例
 /// </summary>
 public JoinExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, List <DbExpression> qJoin)
     : base(provider, aliases, null, false)
 {
     _qJoin    = qJoin;
     _aliases  = aliases;
     _provider = provider;
 }
Пример #3
0
        /// <summary>
        /// 追加列名
        /// </summary>
        /// <param name="aliases">表别名</param>
        /// <param name="expression">列名表达式</param>
        /// <returns>返回解析到的表别名</returns>
        public string AppendMember(TableAliasCache aliases, Expression expression)
        {
            Expression       exp = expression;
            LambdaExpression lambdaExpression = exp as LambdaExpression;

            if (lambdaExpression != null)
            {
                exp = lambdaExpression.Body;
            }

            if (expression.CanEvaluate())
            {
                ConstantExpression c     = expression.Evaluate();
                string             value = this.GetSqlValue(c.Value);
                _innerBuilder.Append(value);
                return(value);
            }
            else
            {
                MemberExpression m     = expression as MemberExpression;
                string           alias = aliases == null ? null : aliases.GetTableAlias(m);
                this.AppendMember(alias, m.Member.Name);
                return(alias);
            }
        }
 /// <summary>
 /// 实例化 <see cref="Builder" /> 的新实例
 /// </summary>
 public OracleDeleteDbCommandDefinition(IDbQueryProvider provider, TableAliasCache aliases, List <IDbDataParameter> parameters)
     : base(provider, aliases, parameters)
 {
     _provider = provider;
     _aliases  = aliases;
     _onPhrase = _provider.CreateSqlBuilder(parameters);
 }
 /// <summary>
 /// 初始化 <see cref="OracleJoinExpressionVisitor"/> 类的新实例
 /// </summary>
 public OracleJoinExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, List <DbExpression> qJoin, DbExpression qWhere)
     : base(provider, aliases, null, false)
 {
     _provider = provider;
     _qJoin    = qJoin;
     _aliases  = aliases;
     _where    = qWhere;
 }
Пример #6
0
 /// <summary>
 /// 初始化 <see cref="ExpressionVisitorBase"/> 类的新实例
 /// </summary>
 public ExpressionVisitorBase(IDbQueryProvider provider, TableAliasCache aliases, Expression exp, bool useNominate = true)
 {
     _provider      = provider;
     _aliases       = aliases;
     _expression    = exp;
     _visitedMember = new VisitedMemberList();
     _navMembers    = new Dictionary <string, MemberExpression>();
 }
Пример #7
0
        // 获取 CROSS JOIN 子句关联表的的别名
        private void PrepareCrossJoinAlias(DbExpression exp, TableAliasCache aliases)
        {
            LambdaExpression lambdaExp = exp.Expressions[1] as LambdaExpression;

            for (int index = 0; index < lambdaExp.Parameters.Count; ++index)
            {
                aliases.GetTableAlias(lambdaExp.Parameters[index]);
            }
        }
 /// <summary>
 /// 初始化 <see cref="StatisExpressionVisitor"/> 类的新实例
 /// </summary>
 public StatisExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, DbExpression statis, DbExpression groupBy = null, string alias = null)
     : base(provider, aliases, statis.Expressions != null ? statis.Expressions[0] : null, false)
 {
     _provider = provider;
     _aliases  = aliases;
     _statis   = statis;
     _groupBy  = groupBy;
     _alias    = alias;
 }
Пример #9
0
 /// <summary>
 /// 初始化 <see cref="OrderByExpressionVisitor"/> 类的新实例
 /// </summary>
 public OrderByExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, List <DbExpression> qOrder, DbExpression groupBy = null, string alias = null)
     : base(provider, aliases, null, false)
 {
     _qOrder   = qOrder;
     _aliases  = aliases;
     _groupBy  = groupBy;
     _alias    = alias;
     _provider = provider;
 }
        /// <summary>
        /// 实例化 <see cref="SelectDbCommandDefinition"/> 类的新实例
        /// </summary>
        /// <param name="provider">数据查询提供者</param>
        /// <param name="aliases">别名</param>
        /// <param name="parameters">已存在的参数列表</param>
        public SelectDbCommandDefinition(IDbQueryProvider provider, TableAliasCache aliases, List <IDbDataParameter> parameters)
            : base(string.Empty, null, System.Data.CommandType.Text)
        {
            _provider   = provider;
            _aliases    = aliases;
            _navMembers = new Dictionary <string, MemberExpression>();

            _joinFragment  = provider.CreateSqlBuilder(parameters);
            _whereFragment = provider.CreateSqlBuilder(parameters);
        }
Пример #11
0
        /// <summary>
        /// 根据指定表达式取表别名
        /// </summary>
        /// <param name="exp">表达式</param>
        /// <remarks>
        /// t=>t.Id
        /// t.Id
        /// </remarks>
        public string GetTableAlias(Expression exp)
        {
            // p=>p.p
            // p=>p.Id
            // p=>p.t.Id
            // p.Id
            // p.t.Id
            // p.t
            // <>h__TransparentIdentifier0.p.Id
            XFrameworkException.Check.NotNull(exp, "exp");
            string key = TableAliasCache.GetTableAliasKey(exp);

            return(this.GetTableAlias(key));
        }
Пример #12
0
        private static string GetTableAliasKey(Expression exp)
        {
            if (exp == null)
            {
                return(null);
            }

            Expression expression = exp.ReduceUnary();

            //c
            if (exp.CanEvaluate())
            {
                return(null);
            }

            // p
            ParameterExpression paramExp = expression as ParameterExpression;

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

            // a=>a.Id
            LambdaExpression lambdaExp = expression as LambdaExpression;

            if (lambdaExp != null)
            {
                expression = lambdaExp.Body.ReduceUnary();
            }

            // a.Id
            // t.a
            // t.t.a
            // t.a.Id
            MemberExpression memExp = expression as MemberExpression;

            if (memExp == null)
            {
                return(TableAliasCache.GetTableAliasKey(expression));
            }

            if (memExp.Acceptable())
            {
                return(TableAliasCache.GetTableAliasKey(memExp.Expression));
            }

            return(memExp.Member.Name);
        }
Пример #13
0
        // Cross Join
        private void AppendCrossJoin(ISqlBuilder builder, DbExpression exp, TableAliasCache aliases)
        {
            LambdaExpression lambdaExp = exp.Expressions[1] as LambdaExpression;
            Type             type      = lambdaExp.Parameters[1].Type;
            var typeRuntime            = TypeRuntimeInfoCache.GetRuntimeInfo(type);

            builder.Append(' ');
            builder.AppendMember(typeRuntime.TableName, !typeRuntime.IsTemporary);

            string alias = aliases.GetTableAlias(lambdaExp.Parameters[1]);

            builder.Append(' ');
            builder.Append(alias);
            builder.Append(' ');
        }
Пример #14
0
        /// <summary>
        /// 初始化 <see cref="JoinExpressionVisitor"/> 类的新实例
        /// </summary>
        public NpgJoinExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, List <DbExpression> qJoin, NpgCommandType operationType)
            : base(provider, aliases, null, false)
        {
            _qJoin         = qJoin;
            _aliases       = aliases;
            _operationType = operationType;

            if (_operationType == NpgCommandType.DELETE)
            {
                _keywordName = "USING";
            }
            else if (_operationType == NpgCommandType.UPDATE)
            {
                _keywordName = "FROM";
            }
        }
Пример #15
0
        // 获取 LEFT JOIN / INNER JOIN 子句关联表的的别名
        private void PrepareLfInJoinAlias(DbExpression exp, TableAliasCache aliases)
        {
            Type   type = exp.Expressions[0].Type.GetGenericArguments()[0];
            string name = TypeRuntimeInfoCache.GetRuntimeInfo(type).TableName;

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

            if (left.Body.NodeType == ExpressionType.New)
            {
                NewExpression body1 = left.Body as NewExpression;
                NewExpression body2 = right.Body as NewExpression;
                for (int index = 0; index < body1.Arguments.Count; ++index)
                {
                    aliases.GetTableAlias(body1.Arguments[index]);
                }
                for (int index = 0; index < body2.Arguments.Count; ++index)
                {
                    string alias = aliases.GetTableAlias(body2.Arguments[index]);
                    // 记录显示指定的LEFT JOIN 表别名
                    aliases.AddOrUpdateJoinTableAlias(name, alias);
                }
            }
            else if (left.Body.NodeType == ExpressionType.MemberInit)
            {
                MemberInitExpression body1 = left.Body as MemberInitExpression;
                MemberInitExpression body2 = right.Body as MemberInitExpression;
                for (int index = 0; index < body1.Bindings.Count; ++index)
                {
                    aliases.GetTableAlias((body1.Bindings[index] as MemberAssignment).Expression);
                }
                for (int index = 0; index < body2.Bindings.Count; ++index)
                {
                    string alias = aliases.GetTableAlias((body2.Bindings[index] as MemberAssignment).Expression);
                    // 记录显示指定的LEFT JOIN 表别名
                    aliases.AddOrUpdateJoinTableAlias(name, alias);
                }
            }
            else
            {
                aliases.GetTableAlias(exp.Expressions[1]);
                string alias = aliases.GetTableAlias(exp.Expressions[2]);
                // 记录显示指定的LEFT JOIN 表别名
                aliases.AddOrUpdateJoinTableAlias(name, alias);
            }
        }
Пример #16
0
        /// <summary>
        /// 初始化 <see cref="ColumnExpressionVisitor"/> 类的新实例
        /// </summary>
        public ColumnExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, IDbQueryableInfo_Select qQuery)
            : base(provider, aliases, qQuery.Select.Expressions != null ? qQuery.Select.Expressions[0] : null)
        {
            _provider = provider;
            _aliases  = aliases;
            _qQuery   = qQuery;
            _groupBy  = qQuery.GroupBy;
            _include  = qQuery.Include;

            if (_columns == null)
            {
                _columns = new Dictionary <string, Column>();
            }
            _navigations        = new NavigationCollection();
            _navChainHopper     = new List <string>(10);
            _visitedNavigations = new Dictionary <string, string>(8);
        }
        /// <summary>
        /// 实例化 <see cref="Builder" /> 的新实例
        /// </summary>
        public NpgDeleteDbCommandDefinition(IDbQueryProvider provider, TableAliasCache aliases, NpgCommandType operationType, List <IDbDataParameter> parameters)
            : base(provider, aliases, parameters)
        {
            _provider      = provider;
            _aliases       = aliases;
            _onPhrase      = _provider.CreateSqlBuilder(parameters);
            _operationType = operationType;

            if (_operationType == NpgCommandType.DELETE)
            {
                _keywordName = "USING";
            }
            else if (_operationType == NpgCommandType.UPDATE)
            {
                _keywordName = "FROM";
            }
        }
Пример #18
0
        // 获取 JOIN 子句关联表的的别名
        protected TableAliasCache PrepareAlias <T>(DbQueryableInfo_Select <T> query)
        {
            TableAliasCache aliases = new TableAliasCache((query.Join != null ? query.Join.Count : 0) + 1);

            foreach (DbExpression exp in query.Join)
            {
                // [INNER/LEFT JOIN]
                if (exp.DbExpressionType == DbExpressionType.GroupJoin || exp.DbExpressionType == DbExpressionType.Join || exp.DbExpressionType == DbExpressionType.GroupRightJoin)
                {
                    this.PrepareLfInJoinAlias(exp, aliases);
                }
                else if (exp.DbExpressionType == DbExpressionType.SelectMany)
                {
                    this.PrepareCrossJoinAlias(exp, aliases);
                }
            }

            return(aliases);
        }
 /// <summary>
 /// 初始化 <see cref="NpgWhereExpressionVisitor"/> 类的新实例
 /// </summary>
 public NpgWhereExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, DbExpression exp)
     : base(provider, aliases, exp)
 {
     _expression = exp != null && exp.Expressions != null ? exp.Expressions[0] : null;
 }
        // 添加导航属性关联
        protected override void AppendNavigation()
        {
            if (this.NavMembers == null || this.NavMembers.Count == 0)
            {
                return;
            }

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

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

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

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

                if (!m.Expression.Acceptable())
                {
                    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).TableName;
                    innerAlias = _aliases.GetJoinTableAlias(name);

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

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

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

                Type type         = m.Type;
                var  typeRumtime2 = TypeRuntimeInfoCache.GetRuntimeInfo(type);
                if (type.IsGenericType)
                {
                    type = type.GetGenericArguments()[0];
                }
                jf.Append(' ');
                jf.AppendMember(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++)
                {
                    _onPhrase.Append(alias1);
                    _onPhrase.Append('.');
                    _onPhrase.AppendMember(attribute.InnerKeys[i]);
                    _onPhrase.Append(" = ");
                    _onPhrase.Append(alias2);
                    _onPhrase.Append('.');
                    _onPhrase.AppendMember(attribute.OuterKeys[i]);
                }

                if (index < this.NavMembers.Count - 1)
                {
                    jf.Append(',');
                    jf.AppendNewLine();
                }
            }
        }
 /// <summary>
 /// 初始化 <see cref="HavingExpressionVisitor"/> 类的新实例
 /// </summary>
 public HavingExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, DbExpression having, DbExpression groupBy)
     : base(provider, aliases, having != null && having.Expressions != null ? having.Expressions[0] : null)
 {
     _groupBy = groupBy;
     _aliases = aliases;
 }
        // LEFT OR INNER JOIN
        private void AppendLfInJoin(ISqlBuilder jf, ISqlBuilder wf, ISqlBuilder on, DbExpression exp, TableAliasCache aliases)
        {
            bool             useExists = false;
            LambdaExpression left      = exp.Expressions[1] as LambdaExpression;
            LambdaExpression right     = exp.Expressions[2] as LambdaExpression;
            NewExpression    body1     = left.Body as NewExpression;
            NewExpression    body2     = right.Body as NewExpression;

            // t0(t1)
            string alias = body1 == null
                ? aliases.GetTableAlias(exp.Expressions[2])
                : aliases.GetTableAlias(right.Parameters[0]);//(body2.Arguments[0]);

            IDbQueryable sQuery = (IDbQueryable)((exp.Expressions[0] as ConstantExpression).Value);

            if (sQuery.DbExpressions.Count == 1 && sQuery.DbExpressions[0].DbExpressionType == DbExpressionType.GetTable)
            {
                useExists = true;
                if ((wf != null && wf.Length > 0) || (on != null && on.Length > 0))
                {
                    wf.AppendNewLine();
                    if (wf != null && wf.Length > 0)
                    {
                        wf.Append("AND ");
                    }
                }

                wf.Append("EXISTS(");
                wf.Indent += 1;
                wf.AppendNewLine();
                wf.Append("SELECT 1 FROM ");

                Type type        = exp.Expressions[0].Type.GetGenericArguments()[0];
                var  typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(type);
                wf.AppendMember(typeRuntime.TableName, !typeRuntime.IsTemporary);
                wf.Append(' ');
                wf.Append(alias);

                wf.AppendNewLine();
                wf.Append("WHERE ");
            }
            else
            {
                useExists = true;
                if ((wf != null && wf.Length > 0) || (on != null && on.Length > 0))
                {
                    wf.AppendNewLine();
                    if (wf != null && wf.Length > 0)
                    {
                        wf.Append("AND ");
                    }
                }

                wf.Append("EXISTS(");
                wf.Indent += 1;
                wf.AppendNewLine();
                wf.Append("SELECT 1 FROM(");
                var cmd2 = sQuery.Resolve(wf.Indent + 1, false, wf.Parameters);
                wf.Append(cmd2.CommandText);
                wf.AppendNewLine();
                wf.Append(')');
                wf.Append(' ');
                wf.Append(alias);
                wf.Append(" WHERE ");
            }

            ISqlBuilder builder = useExists ? wf : on;

            if (body1 == null)
            {
                builder.AppendMember(aliases, left.Body.ReduceUnary());
                builder.Append(" = ");
                builder.AppendMember(aliases, right.Body.ReduceUnary());
            }
            else
            {
                for (int index = 0; index < body1.Arguments.Count; ++index)
                {
                    builder.AppendMember(aliases, body1.Arguments[index]);
                    builder.Append(" = ");
                    builder.AppendMember(aliases, body2.Arguments[index]);
                    if (index < body1.Arguments.Count - 1)
                    {
                        builder.Append(" AND ");
                    }
                }
            }

            //if (_where != null && _where.Expressions != null) this.AppendWhere(builder, right);

            if (useExists)
            {
                wf.Indent -= 1;
                wf.AppendNewLine();
                wf.Append(')');
            }
        }
 // Cross Join
 private void AppendCrossJoin(ISqlBuilder jf, DbExpression exp, TableAliasCache aliases)
 {
     throw new NotSupportedException("Oracle not support.");
 }
Пример #24
0
        // LEFT OR INNER JOIN
        private void AppendLfInJoin(ISqlBuilder builder, DbExpression exp, TableAliasCache aliases)
        {
            builder.Append(' ');
            IDbQueryable sQuery = (IDbQueryable)((exp.Expressions[0] as ConstantExpression).Value);

            if (sQuery.DbExpressions.Count == 1 && sQuery.DbExpressions[0].DbExpressionType == DbExpressionType.GetTable)
            {
                Type type        = exp.Expressions[0].Type.GetGenericArguments()[0];
                var  typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(type);
                builder.AppendMember(typeRuntime.TableName, !typeRuntime.IsTemporary);
            }
            else
            {
                // 嵌套
                var cmd = sQuery.Resolve(builder.Indent + 1, false, builder.Parameters);
                builder.Append("(");
                builder.AppendNewLine(cmd.CommandText);
                builder.Append(')');
            }


            LambdaExpression left  = exp.Expressions[1] as LambdaExpression;
            LambdaExpression right = exp.Expressions[2] as LambdaExpression;

            // t0(t1)
            string alias = !(left.Body.NodeType == ExpressionType.New || left.Body.NodeType == ExpressionType.MemberInit)
                ? aliases.GetTableAlias(exp.Expressions[2])
                : aliases.GetTableAlias(right.Parameters[0]);//(body2.Arguments[0]);

            builder.Append(' ');
            builder.Append(alias);
            builder.Append(' ');

            // ON a.Name = b.Name AND a.Id = b.Id
            builder.Append("ON ");

            if (left.Body.NodeType == ExpressionType.New)
            {
                NewExpression body1 = left.Body as NewExpression;
                NewExpression body2 = right.Body as NewExpression;

                for (int index = 0; index < body1.Arguments.Count; ++index)
                {
                    builder.AppendMember(aliases, body1.Arguments[index]);
                    builder.Append(" = ");
                    builder.AppendMember(aliases, body2.Arguments[index]);
                    if (index < body1.Arguments.Count - 1)
                    {
                        builder.Append(" AND ");
                    }
                }
            }
            else if (left.Body.NodeType == ExpressionType.MemberInit)
            {
                MemberInitExpression body1 = left.Body as MemberInitExpression;
                MemberInitExpression body2 = right.Body as MemberInitExpression;

                for (int index = 0; index < body1.Bindings.Count; ++index)
                {
                    builder.AppendMember(aliases, (body1.Bindings[index] as MemberAssignment).Expression);
                    builder.Append(" = ");
                    builder.AppendMember(aliases, (body2.Bindings[index] as MemberAssignment).Expression);
                    if (index < body1.Bindings.Count - 1)
                    {
                        builder.Append(" AND ");
                    }
                }
            }
            else
            {
                builder.AppendMember(aliases, left.Body.ReduceUnary());
                builder.Append(" = ");
                builder.AppendMember(aliases, right.Body.ReduceUnary());
            }
        }
        // 添加导航属性关联
        protected virtual void AppendNavigation()
        {
            if (this._navMembers == null || this._navMembers.Count == 0)
            {
                return;
            }

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

            foreach (var kvp in _navMembers)
            {
                string              key         = kvp.Key;
                MemberExpression    m           = kvp.Value;
                TypeRuntimeInfo     typeRuntime = TypeRuntimeInfoCache.GetRuntimeInfo(m.Expression.Type);
                ForeignKeyAttribute attribute   = typeRuntime.GetInvokerAttribute <ForeignKeyAttribute>(m.Member.Name);

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

                if (!m.Expression.Acceptable())
                {
                    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).TableName;
                    innerAlias = _aliases.GetJoinTableAlias(name);

                    if (string.IsNullOrEmpty(innerAlias))
                    {
                        string keyLeft = mLeft.GetKeyWidthoutAnonymous();
                        if (_navMembers.ContainsKey(keyLeft))
                        {
                            innerKey = keyLeft;
                        }
                    }
                }

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


                builder.AppendNewLine();
                builder.Append("LEFT JOIN ");
                Type type = m.Type;
                if (type.IsGenericType)
                {
                    type = type.GetGenericArguments()[0];
                }
                var typeRuntime2 = TypeRuntimeInfoCache.GetRuntimeInfo(type);
                builder.AppendMember(typeRuntime2.TableName, !typeRuntime2.IsTemporary);
                builder.Append(" ");
                builder.Append(alias2);
                builder.Append(" ON ");
                for (int i = 0; i < attribute.InnerKeys.Length; i++)
                {
                    builder.Append(alias1);
                    builder.Append('.');
                    builder.AppendMember(attribute.InnerKeys[i]);
                    builder.Append(" = ");
                    builder.Append(alias2);
                    builder.Append('.');
                    builder.AppendMember(attribute.OuterKeys[i]);

                    if (i < attribute.InnerKeys.Length - 1)
                    {
                        builder.Append(" AND ");
                    }
                }
            }
        }
Пример #26
0
 /// <summary>
 /// 初始化 <see cref="NpgUpdateExpressionVisitor"/> 类的新实例
 /// </summary>
 public NpgUpdateExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, Expression exp)
     : base(provider, aliases, exp)
 {
     _provider = provider;
     _aliases  = aliases;
 }
Пример #27
0
 /// <summary>
 /// 追加列名
 /// </summary>
 /// <param name="expression">列名表达式</param>
 /// <param name="aliases">表别名</param>
 /// <returns>返回解析到的表别名</returns>
 public Expression AppendMember(Expression expression, TableAliasCache aliases)
 {
     this.AppendMember(aliases, expression);
     return(expression);
 }
Пример #28
0
 /// <summary>
 /// 初始化 <see cref="GroupByExpressionVisitor"/> 类的新实例
 /// </summary>
 public GroupByExpressionVisitor(IDbQueryProvider provider, TableAliasCache aliases, DbExpression groupBy)
     : base(provider, aliases, groupBy != null ? groupBy.Expressions[0] : null, false)
 {
 }