private static bool IsAggregateWithProjection(MethodCallExpression call)
            {
                if (call.Arguments.Count != 2)
                {
                    return(false); // Aggregates with projection have exactly 2 parameters
                }
                var kind = QueryableVisitor.GetQueryableMethod(call);

                if (kind == null)
                {
                    return(false); // Not a queryable method
                }
                switch (kind.Value)
                {
                case QueryableMethodKind.Max:
                case QueryableMethodKind.Min:
                case QueryableMethodKind.Sum:
                case QueryableMethodKind.Average:
                case QueryableMethodKind.Count:
                    return(true);

                default:
                    return(false);
                }
            }
Example #2
0
    public static IQueryable <T> Expand <T>(this IQueryable <T> query)
    {
        var        visitor     = new QueryableVisitor();
        Expression expression2 = visitor.Visit(query.Expression);

        return(query.Expression != expression2?query.Provider.CreateQuery <T>(expression2) : query);
    }
        protected override Expression VisitMethodCall(MethodCallExpression mc)
        {
            var methodKind = QueryableVisitor.GetQueryableMethod(mc);

            if (methodKind == QueryableMethodKind.Select)
            {
                var selectSource = mc.Arguments[0] as MethodCallExpression;
                if (selectSource != null)
                {
                    var sourceMethodKind = QueryableVisitor.GetQueryableMethod(selectSource);
                    if (sourceMethodKind == QueryableMethodKind.GroupBy)
                    {
                        var projection      = mc.Arguments[1].StripQuotes();
                        var newSelectSource = VisitGroupBy(selectSource, projection);
                        if (newSelectSource != selectSource)
                        {
                            return(QueryFactory.Select(newSelectSource, projection));
                        }
                    }
                }
            }
            else if (methodKind == QueryableMethodKind.GroupBy)
            {
                var newGroupBy = VisitGroupBy(mc, null);
                if (newGroupBy != mc)
                {
                    return(newGroupBy);
                }
            }
            return(base.VisitMethodCall(mc));
        }
        public bool Extract(Expression expression)
        {
            var result = new Stack <Pair <LambdaExpression, Direction> >();

            while (true)
            {
                if (expression.NodeType == ExpressionType.Call)
                {
                    var call   = (MethodCallExpression)expression;
                    var method = QueryableVisitor.GetQueryableMethod(call);
                    if (method != null && IsSort(method.Value))
                    {
                        var source     = call.Arguments[0];
                        var projection = call.Arguments[1].StripQuotes();
                        var direction  = GetDirection(method.Value);
                        result.Push(new Pair <LambdaExpression, Direction>(projection, direction));
                        expression = source;
                        if (IsThenBy(method.Value))
                        {
                            continue;
                        }
                    }
                }
                break;
            }

            if (result.Count == 0)
            {
                BaseExpression  = null;
                SortExpressions = null;
                return(false);
            }

            BaseExpression  = expression;
            SortExpressions = new DirectionCollection <LambdaExpression>();
            foreach (var item in result)
            {
                SortExpressions.Add(item.First, item.Second);
            }
            return(true);
        }