예제 #1
0
        /// <summary>
        /// Returns the member expressions in the expression hierarchy of the <paramref name="expression"/>
        /// </summary>
        /// <param name="expression">The expression to search</param>
        /// <returns>A collection of <see cref="MemberExpression"/> objects</returns>
        internal static IEnumerable <MemberExpression> GetMemberExpressions(this Expression expression)
        {
            List <MemberExpression> members = new();

            VisitorHelper.VisitMembers(expression, (expr, recurse) =>
            {
                members.Add(expr);
                return(recurse(expr));
            });
            return(members);
        }
예제 #2
0
        /// <summary>
        /// Walk the expression and compute all the subtrees that are not dependent on any
        /// of the expressions parameters.
        /// </summary>
        /// <param name="expression">The expression to analyze.</param>
        /// <returns>A collection of all the expression subtrees that are independent from the expression parameters.</returns>
        internal static List <Expression> FindIndependentSubtrees(this Expression expression)
        {
            List <Expression> subtrees = new();

            // The dependenty and isMemberInit flags are used to communicate between different layers
            // of the recursive visitor.
            bool dependent    = false;
            bool isMemberInit = false;

            // Walk the tree, finding the independent subtrees
            VisitorHelper.VisitAll(expression, (expr, recurse) =>
            {
                if (expr != null)
                {
                    bool parentIsDependent  = dependent;
                    bool parentIsMemberInit = isMemberInit;

                    // Set flags
                    dependent    = false;
                    isMemberInit = expr is MemberInitExpression;

                    // Recurse
                    recurse(expr);

                    // If nothing in my subtree is dependent
                    if (!dependent)
                    {
                        // A NewExpression itself will appear to be indepentt, but if the parent is a MemberInitExpression,
                        // then the NewExpression can't be evaluated by itself.  The MemberInitExpression will determine
                        // if the full expression is dependent or not, so don't check it here.
                        if (expr is NewExpression newExpression && parentIsMemberInit)
                        {
                            return(expr);
                        }

                        // The current node is independent if it's not related to the parameter and it's not the constant query root.
                        ConstantExpression constant = expr as ConstantExpression;
                        if (expr.NodeType == ExpressionType.Parameter || (constant?.Value is IQueryable))
                        {
                            dependent = true;
                        }
                        else
                        {
                            subtrees.Add(expr);
                        }
                    }