protected virtual Expression VisitAggregate(AggregateExpression aggregate)
        {
            var exp = Visit(aggregate.Argument);
            if (exp != aggregate.Argument)
                return new AggregateExpression(aggregate.Type, aggregate.AggregateType, exp, aggregate.Distinct);

            return aggregate;
        }
 private void AverageAggregate(AggregateExpression aggregate)
 {
     var old = _currentAggregateName;
     _currentAggregateName = old + "Cnt";
     CountAggregate(aggregate);
     _currentAggregateName = old + "Sum";
     SumAggregate(aggregate);
     _currentAggregateName = old;
 }
示例#3
0
        protected virtual Expression VisitAggregate(AggregateExpression aggregate)
        {
            var exp = Visit(aggregate.Argument);

            if (exp != aggregate.Argument)
            {
                return(new AggregateExpression(aggregate.Type, aggregate.AggregateType, exp, aggregate.Distinct));
            }

            return(aggregate);
        }
        protected override Expression VisitAggregate(AggregateExpression aggregate)
        {
            switch (aggregate.AggregateType)
            {
                case AggregateType.Average:
                    _returnValues.Add(new KeyValuePair<string, string>(_currentAggregateName, string.Format("value.{0}Sum/value.{0}Cnt", _currentAggregateName)));
                    break;
                case AggregateType.Count:
                case AggregateType.Max:
                case AggregateType.Min:
                case AggregateType.Sum:
                    _returnValues.Add(new KeyValuePair<string, string>(_currentAggregateName, "value." + _currentAggregateName));
                    break;
            }

            return aggregate;
        }
        protected override Expression VisitAggregate(AggregateExpression aggregate)
        {
            switch (aggregate.AggregateType)
            {
                case AggregateType.Average:
                    _initMap[_currentAggregateName + "Sum"] = _formatter.FormatJavascript(aggregate.Argument);
                    _initMap[_currentAggregateName + "Cnt"] = "1";
                    break;
                case AggregateType.Count:
                    _initMap[_currentAggregateName] = "1";
                    break;
                case AggregateType.Max:
                case AggregateType.Min:
                case AggregateType.Sum:
                    _initMap[_currentAggregateName] = _formatter.FormatJavascript(aggregate.Argument);
                    break;
            }

            return aggregate;
        }
        protected override Expression VisitAggregate(AggregateExpression aggregate)
        {
            switch (aggregate.AggregateType)
            {
                case AggregateType.Average:
                    AverageAggregate(aggregate);
                    break;
                case AggregateType.Count:
                    CountAggregate(aggregate);
                    break;
                case AggregateType.Max:
                    MaxAggregate(aggregate);
                    break;
                case AggregateType.Min:
                    MinAggregate(aggregate);
                    break;
                case AggregateType.Sum:
                    SumAggregate(aggregate);
                    break;
            }

            return aggregate;
        }
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     return aggregate;
 }
        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 CompareAggregate(AggregateExpression a, AggregateExpression b)
 {
     return(a.AggregateType == b.AggregateType && Compare(a.Argument, b.Argument));
 }
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     _hasAggregate = true;
     return aggregate;
 }
 private void MaxAggregate(AggregateExpression aggregate)
 {
     _declare.AppendFormat("var {0} = Number.MIN_VALUE;", _currentAggregateName);
     _loop.AppendFormat("if(doc.{0} > {0}) {0} = doc.{0};", _currentAggregateName);
     _returnValues.Add(new KeyValuePair<string, string>(_currentAggregateName, _currentAggregateName));
 }
 private void CountAggregate(AggregateExpression aggregate)
 {
     _declare.AppendFormat("var {0} = 0;", _currentAggregateName);
     _loop.AppendFormat("{0} += doc.{0};", _currentAggregateName);
     _returnValues.Add(new KeyValuePair<string, string>(_currentAggregateName, _currentAggregateName));
 }
 protected virtual bool CompareAggregate(AggregateExpression a, AggregateExpression b)
 {
     return a.AggregateType == b.AggregateType && Compare(a.Argument, b.Argument);
 }