コード例 #1
0
 protected override Expression VisitJoin(JoinExpression join)
 {
     join = (JoinExpression)base.VisitJoin(join);
     if ((join.Join == JoinType.CrossApply) || (join.Join == JoinType.OuterApply))
     {
         if (join.Right is TableExpression)
         {
             return(new JoinExpression(JoinType.CrossJoin, join.Left, join.Right, null));
         }
         SelectExpression right = join.Right as SelectExpression;
         if ((((right != null) && (right.Take == null)) && ((right.Skip == null) && !AggregateChecker.HasAggregates(right))) && ((right.GroupBy == null) || (right.GroupBy.Count == 0)))
         {
             SelectExpression     source = right.SetWhere(null);
             HashSet <TableAlias> set    = ReferencedAliasGatherer.Gather(source);
             HashSet <TableAlias> other  = DeclaredAliasGatherer.Gather(join.Left);
             set.IntersectWith(other);
             if (set.Count == 0)
             {
                 Expression where = right.Where;
                 right            = source;
                 ProjectedColumns columns = ColumnProjector.ProjectColumns(this.language, where, right.Columns, right.Alias, DeclaredAliasGatherer.Gather(right.From));
                 right = right.SetColumns(columns.Columns);
                 where = columns.Projector;
                 return(new JoinExpression((where == null) ? JoinType.CrossJoin : ((join.Join == JoinType.CrossApply) ? JoinType.InnerJoin : JoinType.LeftOuter), join.Left, right, where));
             }
         }
     }
     return(join);
 }
コード例 #2
0
        public static HashSet <TableAlias> Gather(Expression source)
        {
            ReferencedAliasGatherer gatherer = new ReferencedAliasGatherer();

            gatherer.Visit(source);
            return(gatherer.aliases);
        }
コード例 #3
0
        private bool CanBeJoinCondition(Expression expression, HashSet <TableAlias> left, HashSet <TableAlias> right, HashSet <TableAlias> all)
        {
            HashSet <TableAlias> first = ReferencedAliasGatherer.Gather(expression);
            bool flag  = first.Intersect <TableAlias>(left).Any <TableAlias>();
            bool flag2 = first.Intersect <TableAlias>(right).Any <TableAlias>();
            bool flag3 = first.IsSubsetOf(all);

            return((flag && flag2) && flag3);
        }
コード例 #4
0
        private bool GetEquiJoinKeyExpressions(Expression predicate, TableAlias outerAlias, List <Expression> outerExpressions, List <Expression> innerExpressions)
        {
            if (predicate.NodeType == ExpressionType.Equal)
            {
                BinaryExpression expression       = (BinaryExpression)predicate;
                ColumnExpression columnExpression = this.GetColumnExpression(expression.Left);
                ColumnExpression expression3      = this.GetColumnExpression(expression.Right);
                if ((columnExpression != null) && (expression3 != null))
                {
                    if (columnExpression.Alias == outerAlias)
                    {
                        outerExpressions.Add(expression.Left);
                        innerExpressions.Add(expression.Right);
                        return(true);
                    }
                    if (expression3.Alias == outerAlias)
                    {
                        innerExpressions.Add(expression.Left);
                        outerExpressions.Add(expression.Right);
                        return(true);
                    }
                }
            }
            bool flag = false;

            Expression[] expressionArray = predicate.Split(new ExpressionType[] { ExpressionType.And, ExpressionType.AndAlso });
            if (expressionArray.Length > 1)
            {
                foreach (Expression expression4 in expressionArray)
                {
                    if (ReferencedAliasGatherer.Gather(expression4).Contains(outerAlias))
                    {
                        if (!this.GetEquiJoinKeyExpressions(expression4, outerAlias, outerExpressions, innerExpressions))
                        {
                            return(false);
                        }
                        flag = true;
                    }
                }
            }
            return(flag);
        }