FindExists() public static method

public static FindExists ( Expression expression, Predicate isMatch ) : bool
expression System.Linq.Expressions.Expression
isMatch Predicate
return bool
Ejemplo n.º 1
0
        protected override Expression VisitSelect(SqlSelectExpression select)
        {
            var saveIsOuterMostSelect = this.isOuterMostSelect;

            try
            {
                this.isOuterMostSelect = false;

                select = (SqlSelectExpression)base.VisitSelect(select);

                var hasOrderBy = select.OrderBy != null && select.OrderBy.Count > 0;

                if (hasOrderBy)
                {
                    this.PrependOrderings(select.OrderBy.Select(c => (SqlOrderByExpression)c));
                }

                var canHaveOrderBy     = saveIsOuterMostSelect && !SqlExpressionFinder.FindExists(select, c => c.NodeType == (ExpressionType)SqlExpressionType.Aggregate || c.NodeType == (ExpressionType)SqlExpressionType.AggregateSubquery);
                var canPassOnOrderings = !saveIsOuterMostSelect;

                var columns = select.Columns;
                IEnumerable <Expression> orderings = (canHaveOrderBy) ? this.gatheredOrderings : null;

                if (this.gatheredOrderings != null)
                {
                    if (canPassOnOrderings)
                    {
                        var producedAliases = AliasesProduced.Gather(select.From);
                        var project         = this.RebindOrderings(this.gatheredOrderings, select.Alias, producedAliases, select.Columns);

                        this.gatheredOrderings = project.Orderings;

                        columns = project.Columns;
                    }
                    else
                    {
                        this.gatheredOrderings = null;
                    }
                }

                if (orderings != select.OrderBy || columns != select.Columns)
                {
                    select = new SqlSelectExpression(select.Type, select.Alias, columns, select.From, select.Where, orderings, select.GroupBy, select.Distinct, select.Skip, select.Take, select.ForUpdate);
                }

                return(select);
            }
            finally
            {
                this.isOuterMostSelect = saveIsOuterMostSelect;
            }
        }
        protected override Expression VisitMethodCall(MethodCallExpression methodCallExpression)
        {
            if (!(methodCallExpression.Method.DeclaringType == typeof(Queryable) ||
                  methodCallExpression.Method.DeclaringType == typeof(Enumerable) ||
                  methodCallExpression.Method.DeclaringType == typeof(QueryableExtensions)))
            {
                return(base.VisitMethodCall(methodCallExpression));
            }

            var saveInsideSkipTake = this.insideSkipTake;

            if (methodCallExpression.Method.Name == "Skip" || methodCallExpression.Method.Name == "Take")
            {
                this.insideSkipTake = true;

                try
                {
                    var retval = base.VisitMethodCall(methodCallExpression);

                    if (!saveInsideSkipTake)
                    {
                        foreach (var includeSelector in this.includeSelectors)
                        {
                            retval = Expression.Call(MethodInfoFastRef.QueryableExtensionsIncludeMethod.MakeGenericMethod(retval.Type.GetGenericArguments()[0], includeSelector.Body.Type), retval, includeSelector);
                        }
                    }

                    return(retval);
                }
                finally
                {
                    this.insideSkipTake = saveInsideSkipTake;
                }
            }
            else if (methodCallExpression.Method.Name == "Select" && this.insideSkipTake)
            {
                var lambda = methodCallExpression.Arguments[1].StripQuotes();

                var saveSelector = this.selector;

                if (this.selector != null)
                {
                    var body = SqlExpressionReplacer.Replace(this.selector.Body, this.selector.Parameters[0], lambda.Body);

                    this.selector = Expression.Lambda(body, lambda.Parameters[0]);
                }
                else
                {
                    this.selector = lambda;
                }

                try
                {
                    return(base.VisitMethodCall(methodCallExpression));
                }
                finally
                {
                    this.selector = saveSelector;
                }
            }
            else if (methodCallExpression.Method.Name == "Include" && this.insideSkipTake)
            {
                var source = Visit(methodCallExpression.Arguments[0]);

                List <MemberInfo> path;

                if (this.selector == null)
                {
                    path = new List <MemberInfo>();
                }
                else
                {
                    path = ParameterPathFinder.Find(this.selector);
                }

                if (path == null)
                {
                    ParameterPathFinder.Find(this.selector);

                    return(source);
                }

                bool IsRelatedObjectsMemberExpression(Expression expression)
                {
                    return(expression is MemberExpression memberExpression &&
                           memberExpression.Member.GetMemberReturnType().IsGenericType &&
                           memberExpression.Member.GetMemberReturnType().GetGenericTypeDefinition() == typeof(RelatedDataAccessObjects <>));
                }

                var includeSelector = methodCallExpression.Arguments[1].StripQuotes();
                var includesRelatedDataAccessObjects = SqlExpressionFinder.FindExists(includeSelector.Body, IsRelatedObjectsMemberExpression);

                if (includesRelatedDataAccessObjects)
                {
                    // Create a new include selector adjusting for any additional member accesses necessary because of select projections

                    var oldParam = includeSelector.Parameters[0];
                    var oldBody  = includeSelector.Body;

                    var newParam = path.Count > 0 ? Expression.Parameter(path.First().DeclaringType) : oldParam;

                    var replacement = path.Aggregate((Expression)newParam, Expression.MakeMemberAccess, c => c);

                    var newBody = SqlExpressionReplacer.Replace(oldBody, oldParam, replacement);

                    this.includeSelectors.Add(Expression.Lambda(newBody, newParam));
                }

                return(source);
            }

            return(base.VisitMethodCall(methodCallExpression));
        }