Пример #1
0
        /// <summary>
        ///     Performs funcletization on the given expression. Also returns a delegates that can be used
        ///     to determine if the entire tree needs to be recompiled.
        /// </summary>
        internal Expression Funcletize(Expression expression, out Func <bool> recompileRequired)
        {
            DebugCheck.NotNull(expression);

            // Find all candidates for funcletization. Some sub-expressions are reduced to constants,
            // others are reduced to variables. The rules vary based on the _mode.
            Func <Expression, bool> isClientConstant;
            Func <Expression, bool> isClientVariable;

            expression = ReplaceRootContextParameter(expression);

            if (_mode == Mode.CompiledQueryEvaluation)
            {
                // We lock down closure expressions for compiled queries, so everything is either
                // a constant or a query parameter produced from the explicit parameters to the
                // compiled query delegate.
                isClientConstant = Nominate(expression, IsClosureExpression);
                isClientVariable = Nominate(expression, IsCompiledQueryParameterVariable);
            }
            else if (_mode == Mode.CompiledQueryLockdown)
            {
                // When locking down a compiled query, we can evaluate all closure expressions.
                isClientConstant = Nominate(expression, IsClosureExpression);
                isClientVariable = (exp) => false;
            }
            else
            {
                Debug.Assert(_mode == Mode.ConventionalQuery, "No other options...");

                // There are no variable parameters outside of compiled queries, so everything is
                // either a constant or a closure expression.
                isClientConstant = Nominate(expression, IsImmutable);
                isClientVariable = Nominate(expression, IsClosureExpression);
            }

            // Now rewrite given nomination functions
            var visitor = new FuncletizingVisitor(this, isClientConstant, isClientVariable);
            var result  = visitor.Visit(expression);

            recompileRequired = visitor.GetRecompileRequiredFunction();

            return(result);
        }
Пример #2
0
        /// <summary>
        /// Performs funcletization on the given expression. Also returns a delegates that can be used
        /// to determine if the entire tree needs to be recompiled.
        /// </summary>
        internal Expression Funcletize(Expression expression, out Func<bool> recompileRequired)
        {
            EntityUtil.CheckArgumentNull(expression, "expression");

            // Find all candidates for funcletization. Some sub-expressions are reduced to constants,
            // others are reduced to variables. The rules vary based on the _mode.
            Func<Expression, bool> isClientConstant;
            Func<Expression, bool> isClientVariable;

            expression = ReplaceRootContextParameter(expression);

            if (_mode == Mode.CompiledQueryEvaluation)
            {
                // We lock down closure expressions for compiled queries, so everything is either
                // a constant or a query parameter produced from the explicit parameters to the
                // compiled query delegate.
                isClientConstant = Nominate(expression, this.IsClosureExpression);
                isClientVariable = Nominate(expression, this.IsCompiledQueryParameterVariable);
            }
            else if (_mode == Mode.CompiledQueryLockdown)
            {
                // When locking down a compiled query, we can evaluate all closure expressions.
                isClientConstant = Nominate(expression, this.IsClosureExpression);
                isClientVariable = (exp) => false;
            }
            else
            {
                Debug.Assert(_mode == Mode.ConventionalQuery, "No other options...");

                // There are no variable parameters outside of compiled queries, so everything is
                // either a constant or a closure expression.
                isClientConstant = Nominate(expression, this.IsImmutable);
                isClientVariable = Nominate(expression, this.IsClosureExpression);
            }

            // Now rewrite given nomination functions
            FuncletizingVisitor visitor = new FuncletizingVisitor(this, isClientConstant, isClientVariable);
            Expression result = visitor.Visit(expression);
            recompileRequired = visitor.GetRecompileRequiredFunction();
            
            return result;
        }