public AggregateSubqueryExpression(Alias groupByAlias, Expression aggregateInGroupSelect, ScalarExpression aggregateAsSubquery)
     : base(MongoExpressionType.AggregateSubquery, aggregateAsSubquery.Type)
 {
     GroupByAlias = groupByAlias;
     AggregateInGroupSelect = aggregateInGroupSelect;
     AggregateAsSubquery = aggregateAsSubquery;
 }
 public AggregateSubqueryExpression(Alias groupByAlias, Expression aggregateInGroupSelect, ScalarExpression aggregateAsSubquery)
     : base(MongoExpressionType.AggregateSubquery, aggregateAsSubquery.Type)
 {
     GroupByAlias           = groupByAlias;
     AggregateInGroupSelect = aggregateInGroupSelect;
     AggregateAsSubquery    = aggregateAsSubquery;
 }
示例#3
0
        protected virtual Expression VisitScalar(ScalarExpression scalar)
        {
            SelectExpression select = (SelectExpression)Visit(scalar.Select);

            if (select != scalar.Select)
            {
                return(new ScalarExpression(scalar.Type, select));
            }
            return(scalar);
        }
示例#4
0
        protected virtual Expression VisitAggregateSubquery(AggregateSubqueryExpression aggregateSubquery)
        {
            Expression       e        = Visit(aggregateSubquery.AggregateAsSubquery);
            ScalarExpression subquery = (ScalarExpression)e;

            if (subquery != aggregateSubquery.AggregateAsSubquery)
            {
                return(new AggregateSubqueryExpression(aggregateSubquery.GroupByAlias, aggregateSubquery.AggregateInGroupSelect, subquery));
            }
            return(aggregateSubquery);
        }
 protected override Expression VisitScalar(ScalarExpression scalar)
 {
     return scalar;
 }
        private Expression BindAggregate(Expression source, MethodInfo method, LambdaExpression argument, bool isRoot)
        {
            var returnType = method.ReturnType;
            var aggregateType = GetAggregateType(method.Name);
            bool hasPredicateArgument = HasPredicateArgument(aggregateType);
            bool distinct = false;
            bool argumentWasPredicate = false;

            var methodCallExpression = source as MethodCallExpression;
            if (methodCallExpression != null && !hasPredicateArgument && argument == null)
            {
                if (methodCallExpression.Method.Name == "Distinct" && methodCallExpression.Arguments.Count == 1
                    && (methodCallExpression.Method.DeclaringType == typeof(Queryable) || methodCallExpression.Method.DeclaringType == typeof(Enumerable)))
                {
                    source = methodCallExpression.Arguments[0];
                    distinct = true;
                }
            }

            if (argument != null && hasPredicateArgument)
            {
                source = Expression.Call(typeof(Queryable), "Where", method.GetGenericArguments(), source, argument);
                argument = null;
                argumentWasPredicate = true;
            }

            var projection = VisitSequence(source);
            Expression argExpression = null;
            if (argument != null)
            {
                _map[argument.Parameters[0]] = projection.Projector;
                argExpression = Visit(argument.Body);
            }
            else if (!hasPredicateArgument)
                argExpression = projection.Projector;

            var alias = new Alias();
            Expression aggregateExpression = new AggregateExpression(returnType, aggregateType, argExpression, distinct);
            var selectType = typeof(IEnumerable<>).MakeGenericType(returnType);
            string fieldName = "_$agg" + (_aggregateCount++);
            var select = new SelectExpression(alias, new[] { new FieldDeclaration(fieldName, aggregateExpression) }, projection.Source, null);

            if (isRoot)
            {
                var parameter = Expression.Parameter(selectType, "p");
                var lambda = Expression.Lambda(Expression.Call(typeof(Enumerable), "Single", new[] { returnType }, parameter), parameter);
                return new ProjectionExpression(
                    select,
                    new FieldExpression(aggregateExpression, alias, fieldName),
                    lambda);
            }

            var subquery = new ScalarExpression(returnType, select);

            GroupByInfo info;
            if (!argumentWasPredicate && _groupByMap.TryGetValue(projection, out info))
            {
                if (argument != null)
                {
                    _map[argument.Parameters[0]] = info.Element;
                    argExpression = Visit(argument.Body);
                }
                else if (!hasPredicateArgument)
                    argExpression = info.Element;

                aggregateExpression = new AggregateExpression(returnType, aggregateType, argExpression, distinct);

                if (projection == _currentGroupElement)
                    return aggregateExpression;

                return new AggregateSubqueryExpression(info.Alias, aggregateExpression, subquery);
            }

            return subquery;
        }
 protected virtual bool CompareScalar(ScalarExpression a, ScalarExpression b)
 {
     return(Compare(a.Select, b.Select));
 }
 protected virtual Expression VisitScalar(ScalarExpression scalar)
 {
     SelectExpression select = (SelectExpression)Visit(scalar.Select);
     if (select != scalar.Select)
         return new ScalarExpression(scalar.Type, select);
     return scalar;
 }
 protected virtual bool CompareScalar(ScalarExpression a, ScalarExpression b)
 {
     return Compare(a.Select, b.Select);
 }