Exemplo n.º 1
0
            protected override Expression VisitSubQuery(SubQueryExpression subQueryExpression)
            {
                if (_translateToSql)
                {
                    var sqlExpression = _sqlTranslatingExpressionVisitorFactory.Create(
                        _queryModelVisitor,
                        _selectExpression,
                        inProjection: true)
                                        .Visit(subQueryExpression);
                    _sqlMapping[subQueryExpression] = sqlExpression;

                    return(subQueryExpression);
                }

                return(BindSqlToValueBuffer(_sqlMapping[subQueryExpression], subQueryExpression.Type));
            }
 public SqlTranslatingExpressionVisitor CreateSqlTranslatingVisitor(bool bindParentQueries = false)
 {
     return(_sqlTranslatingExpressionVisitorFactory
            .Create(
                QueryModelVisitor,
                SelectExpression,
                bindParentQueries: bindParentQueries));
 }
Exemplo n.º 3
0
 public SqlTranslatingExpressionVisitor CreateSqlTranslatingVisitor()
 => _sqlTranslatingExpressionVisitorFactory.Create(QueryModelVisitor, SelectExpression);
Exemplo n.º 4
0
        protected virtual void OptimizeJoinClause(
            [NotNull] JoinClause joinClause,
            [NotNull] QueryModel queryModel,
            int index,
            [NotNull] Action baseVisitAction,
            [NotNull] MethodInfo operatorToFlatten,
            bool outerJoin = false)
        {
            Check.NotNull(joinClause, nameof(joinClause));
            Check.NotNull(queryModel, nameof(queryModel));
            Check.NotNull(baseVisitAction, nameof(baseVisitAction));
            Check.NotNull(operatorToFlatten, nameof(operatorToFlatten));

            RequiresClientJoin = true;

            var previousQuerySource = FindPreviousQuerySource(queryModel, index);

            var previousSelectExpression
                = previousQuerySource != null
                    ? TryGetQuery(previousQuerySource)
                    : null;

            var previousSelectProjectionCount
                = previousSelectExpression?.Projection.Count ?? -1;

            baseVisitAction();

            if (previousSelectExpression != null)
            {
                var selectExpression = TryGetQuery(joinClause);

                if (selectExpression != null)
                {
                    var sqlTranslatingExpressionVisitor
                        = _sqlTranslatingExpressionVisitorFactory.Create(this);

                    var predicate
                        = sqlTranslatingExpressionVisitor
                          .Visit(
                              Expression.Equal(
                                  joinClause.OuterKeySelector,
                                  joinClause.InnerKeySelector));

                    if (predicate != null)
                    {
                        QueriesBySource.Remove(joinClause);

                        previousSelectExpression.RemoveRangeFromProjection(previousSelectProjectionCount);

                        var tableExpression = selectExpression.Tables.Single();

                        var projection
                            = QueryCompilationContext
                              .QuerySourceRequiresMaterialization(joinClause)
                                ? selectExpression.Projection
                                : Enumerable.Empty <Expression>();

                        var joinExpression
                            = !outerJoin
                                ? previousSelectExpression.AddInnerJoin(tableExpression, projection)
                                : previousSelectExpression.AddOuterJoin(tableExpression, projection);

                        joinExpression.Predicate = predicate;

                        if (outerJoin)
                        {
                            var outerJoinOrderingExtractor = new OuterJoinOrderingExtractor();

                            outerJoinOrderingExtractor.Visit(predicate);

                            foreach (var expression in outerJoinOrderingExtractor.Expressions)
                            {
                                previousSelectExpression
                                .AddToOrderBy(new Ordering(expression, OrderingDirection.Asc));
                            }
                        }

                        Expression
                            = _queryFlattenerFactory
                              .Create(
                                  joinClause,
                                  QueryCompilationContext,
                                  operatorToFlatten,
                                  previousSelectProjectionCount)
                              .Flatten((MethodCallExpression)Expression);

                        RequiresClientJoin = false;
                    }
                }
            }

            if (RequiresClientJoin)
            {
                CheckClientEval(joinClause);
            }
        }
Exemplo n.º 5
0
        /// <summary>
        ///     Visits the given node.
        /// </summary>
        /// <param name="expression"> The expression to visit. </param>
        /// <returns>
        ///     An Expression to the translated input expression.
        /// </returns>
        public override Expression Visit(Expression expression)
        {
            var selectExpression = QueryModelVisitor.TryGetQuery(_querySource);

            if (expression != null &&
                !(expression is ConstantExpression) &&
                !(expression is NewExpression) &&
                !(expression is MemberInitExpression) &&
                selectExpression != null)
            {
                var existingProjectionsCount = selectExpression.Projection.Count;

                var sqlExpression
                    = _sqlTranslatingExpressionVisitorFactory
                      .Create(QueryModelVisitor, selectExpression, inProjection: true)
                      .Visit(expression);

                if (sqlExpression == null)
                {
                    if (expression is QuerySourceReferenceExpression qsre)
                    {
                        if (QueryModelVisitor.ParentQueryModelVisitor != null &&
                            selectExpression.HandlesQuerySource(qsre.ReferencedQuerySource))
                        {
                            selectExpression.ProjectStarTable = selectExpression.GetTableForQuerySource(qsre.ReferencedQuerySource);
                        }
                    }
                    else
                    {
                        QueryModelVisitor.RequiresClientProjection = true;
                    }
                }
                else
                {
                    selectExpression.RemoveRangeFromProjection(existingProjectionsCount);

                    if (!(expression is QuerySourceReferenceExpression))
                    {
                        if (sqlExpression is NullableExpression nullableExpression)
                        {
                            sqlExpression = nullableExpression.Operand;
                        }

                        if (sqlExpression is ColumnExpression)
                        {
                            var index = selectExpression.AddToProjection(sqlExpression);

                            _sourceExpressionProjectionMapping[expression] = selectExpression.Projection[index];

                            return(expression);
                        }
                    }

                    if (!(sqlExpression is ConstantExpression))
                    {
                        var targetExpression
                            = QueryModelVisitor.QueryCompilationContext.QuerySourceMapping
                              .GetExpression(_querySource);

                        if (targetExpression.Type == typeof(ValueBuffer))
                        {
                            var index = selectExpression.AddToProjection(sqlExpression);

                            _sourceExpressionProjectionMapping[expression] = selectExpression.Projection[index];

                            var readValueExpression
                                = _entityMaterializerSource
                                  .CreateReadValueCallExpression(targetExpression, index);

                            var outputDataInfo
                                = (expression as SubQueryExpression)?.QueryModel
                                  .GetOutputDataInfo();

                            if (outputDataInfo is StreamedScalarValueInfo)
                            {
                                // Compensate for possible nulls
                                readValueExpression
                                    = Expression.Coalesce(
                                          readValueExpression,
                                          Expression.Default(expression.Type));
                            }

                            return(Expression.Convert(readValueExpression, expression.Type));
                        }

                        return(expression);
                    }
                }
            }

            return(base.Visit(expression));
        }
        public override Expression Visit(Expression expression)
        {
            var selectExpression = QueryModelVisitor.TryGetQuery(_querySource);

            if (expression != null &&
                !(expression is ConstantExpression) &&
                selectExpression != null)
            {
                var sqlExpression
                    = _sqlTranslatingExpressionVisitorFactory
                      .Create(QueryModelVisitor, selectExpression, inProjection: true)
                      .Visit(expression);

                if (sqlExpression == null)
                {
                    if (!(expression is QuerySourceReferenceExpression))
                    {
                        QueryModelVisitor.RequiresClientProjection = true;
                    }
                }
                else
                {
                    if (!(expression is NewExpression))
                    {
                        AliasExpression aliasExpression;

                        int index;

                        if (!(expression is QuerySourceReferenceExpression))
                        {
                            var columnExpression = sqlExpression.TryGetColumnExpression();

                            if (columnExpression != null)
                            {
                                index = selectExpression.AddToProjection(sqlExpression);

                                aliasExpression = selectExpression.Projection[index] as AliasExpression;

                                if (aliasExpression != null)
                                {
                                    aliasExpression.SourceExpression = expression;
                                }

                                return(expression);
                            }
                        }

                        if (!(sqlExpression is ConstantExpression))
                        {
                            index = selectExpression.AddToProjection(sqlExpression);

                            aliasExpression = selectExpression.Projection[index] as AliasExpression;

                            if (aliasExpression != null)
                            {
                                aliasExpression.SourceExpression = expression;
                            }

                            var targetExpression
                                = QueryModelVisitor.QueryCompilationContext.QuerySourceMapping
                                  .GetExpression(_querySource);

                            if (targetExpression.Type == typeof(ValueBuffer))
                            {
                                var readValueExpression
                                    = _entityMaterializerSource
                                      .CreateReadValueCallExpression(targetExpression, index);

                                var outputDataInfo
                                    = (expression as SubQueryExpression)?.QueryModel
                                      .GetOutputDataInfo();

                                if (outputDataInfo is StreamedScalarValueInfo)
                                {
                                    // Compensate for possible nulls
                                    readValueExpression
                                        = Expression.Coalesce(
                                              readValueExpression,
                                              Expression.Default(expression.Type));
                                }

                                return(Expression.Convert(readValueExpression, expression.Type));
                            }
                        }
                    }
                }
            }

            return(base.Visit(expression));
        }