Exemplo n.º 1
0
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     // COUNT(*) forces all columns to be retained in subquery
     if (aggregate.AggregateName == "Count" && aggregate.Argument == null) {
         this.retainAllColumns = true;
     }
     return base.VisitAggregate(aggregate);
 }
Exemplo n.º 2
0
 protected AggregateExpression UpdateAggregate(AggregateExpression aggregate, Type type, string aggType, Expression arg, bool isDistinct)
 {
     if (type != aggregate.Type || aggType != aggregate.AggregateName || arg != aggregate.Argument || isDistinct != aggregate.IsDistinct)
     {
         return new AggregateExpression(type, aggType, arg, isDistinct);
     }
     return aggregate;
 }
 protected virtual Expression VisitAggregate(AggregateExpression aggregate)
 {
     Expression arg = this.Visit(aggregate.Argument);
     if (arg != aggregate.Argument)
     {
         return new AggregateExpression(aggregate.Type, aggregate.AggregateType, arg, aggregate.IsDistinct);
     }
     return aggregate;
 }
Exemplo n.º 4
0
    protected internal virtual Expression VisitAggregate(AggregateExpression aggregate)
    {
        var expressions = Visit(aggregate.Arguments);

        if (expressions != aggregate.Arguments)
        {
            return(new AggregateExpression(aggregate.Type, aggregate.AggregateFunction, expressions));
        }
        return(aggregate);
    }
Exemplo n.º 5
0
        private void AverageAggregate(AggregateExpression aggregate)
        {
            var old = _currentAggregateName;

            _currentAggregateName = old + "Cnt";
            CountAggregate(aggregate);
            _currentAggregateName = old + "Sum";
            SumAggregate(aggregate);
            _currentAggregateName = old;
        }
Exemplo n.º 6
0
        private AggregateExpression FixCustomMethodReturnType(AggregateExpression expression)
        {
            if (expression.Method != AggregationMethod.Custom)
            {
                return expression;
            }

            var customMethod = GetCustomMethod(expression);
            var typeReference = EdmLibHelpers.GetEdmPrimitiveTypeReferenceOrNull(customMethod.ReturnType);
            return new AggregateExpression(expression.Expression, expression.MethodDefinition, expression.Alias, typeReference);
        }
Exemplo n.º 7
0
        private AggregateExpression FixCustomMethodReturnType(AggregateExpression expression)
        {
            if (expression.Method != AggregationMethod.Custom)
            {
                return(expression);
            }

            var customMethod  = GetCustomMethod(expression);
            var typeReference = customMethod.ReturnType.GetEdmPrimitiveTypeReference();

            return(new AggregateExpression(expression.Expression, expression.MethodDefinition, expression.Alias, typeReference));
        }
Exemplo n.º 8
0
        protected override Expression VisitAggregate(AggregateExpression aggregate)
        {
            var saveInAggregate = this.inAggregate;

            this.inAggregate = true;

            var result = base.VisitAggregate(aggregate);

            this.inAggregate = saveInAggregate;

            return result;
        }
    protected internal override Expression VisitAggregate(AggregateExpression aggregate)
    {
        var saveInAggregate = this.inAggregate;

        this.inAggregate = true;

        var result = base.VisitAggregate(aggregate);

        this.inAggregate = saveInAggregate;

        return(result);
    }
Exemplo n.º 10
0
        protected override Expression VisitAggregate(AggregateExpression aggregate)
        {
            if (aggregate.AggregateType == AggregateType.Average)
            {
                Write("TRUNC(");
                var exp = base.VisitAggregate(aggregate);
                Write(", 20)");
                return(exp);
            }

            return(base.VisitAggregate(aggregate));
        }
Exemplo n.º 11
0
        private object GetAggregatedValue(string key, AggregateExpression expression, IEnumerable <Dictionary <string, object> > group, EdmPrimitiveTypeKind edmPrimitiveType = EdmPrimitiveTypeKind.None, EdmComplexType edmComplexType = null)
        {
            var clrType = GetCLRTypeFromEdmType(edmPrimitiveType);
            var method  = expression.Method;

            switch (method)
            {
            case AggregationMethod.Max: return(Convert.ChangeType(group.Max(r => r.GetValueOrDefault(key)), clrType));

            case AggregationMethod.Min: return(Convert.ChangeType(group.Min(r => r.GetValueOrDefault(key)), clrType));

            case AggregationMethod.Average:
                switch (edmPrimitiveType)
                {
                case EdmPrimitiveTypeKind.Double: return(group.Average(r => (double)r.GetValueOrDefault(key)));

                case EdmPrimitiveTypeKind.Int16: return(group.Average(r => (short)r.GetValueOrDefault(key)));

                case EdmPrimitiveTypeKind.Int32: return(group.Average(r => (int)r.GetValueOrDefault(key)));

                case EdmPrimitiveTypeKind.Int64: return(group.Average(r => (long)r.GetValueOrDefault(key)));

                case EdmPrimitiveTypeKind.Decimal: return(group.Average(r => (decimal)r.GetValueOrDefault(key)));

                default: return(group.Average(r => (int)r.GetValueOrDefault(key)));
                }

            case AggregationMethod.CountDistinct: return(group.Select(r => r.GetValueOrDefault(key)).Distinct().Count());

            case AggregationMethod.VirtualPropertyCount: return(group.Select(r => r).Count());

            case AggregationMethod.Sum:
                switch (edmPrimitiveType)
                {
                case EdmPrimitiveTypeKind.Double: return(group.Sum(r => (double)r.GetValueOrDefault(key)));

                case EdmPrimitiveTypeKind.Int16: return(group.Sum(r => (short)r.GetValueOrDefault(key)));

                case EdmPrimitiveTypeKind.Int32: return(group.Sum(r => (int)r.GetValueOrDefault(key)));

                case EdmPrimitiveTypeKind.Int64: return(group.Sum(r => (long)r.GetValueOrDefault(key)));

                case EdmPrimitiveTypeKind.Decimal: return(group.Sum(r => (decimal)r.GetValueOrDefault(key)));

                default: return(Convert.ChangeType(group.Sum(r => (int)r.GetValueOrDefault(key)), clrType));
                }

            case AggregationMethod.Custom: return(ProcessCustomAggregationValue(expression.MethodDefinition.MethodLabel, group, edmComplexType, key));
            }
            return(null);
        }
Exemplo n.º 12
0
        public virtual List <dynamic> Execute(AggregateExpression agg)
        {
            var           queryResolver = _queryResolverFactory.Get(agg);
            var           sqlString     = queryResolver.ToSqlString();
            List <string> selectFields  = new List <string>();

            foreach (var a in agg.AggregateFields)
            {
                selectFields.Add(DataFieldExpressionHelper.GetAggregationExpression(a.AggregateType, a.AttributeName) + " AS " + a.AttributeName);
            }
            sqlString = string.Format("SELECT {0} FROM ({1}) a", string.Join(",", selectFields).ToLower(), sqlString);

            return(_dataRepository.ExecuteQuery(sqlString, queryResolver.Parameters.Args.ToArray()));
        }
Exemplo n.º 13
0
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     switch (aggregate.AggregateName)
     {
         case "Average":
             this.WriteTruncMaxDecimalDigitsStart();
             base.VisitAggregate(aggregate);
             this.WriteTruncMaxDecimalDigitsEnd();
             break;
         default:
             return base.VisitAggregate(aggregate);
     }
     return aggregate;
 }
Exemplo n.º 14
0
        protected override Expression VisitAggregate(AggregateExpression aggregate)
        {
            switch (aggregate.AggregateName)
            {
            case "Average":
                this.WriteTruncMaxDecimalDigitsStart();
                base.VisitAggregate(aggregate);
                this.WriteTruncMaxDecimalDigitsEnd();
                break;

            default:
                return(base.VisitAggregate(aggregate));
            }
            return(aggregate);
        }
Exemplo n.º 15
0
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     _sb.Append(GetAggregateName(aggregate.AggregateType));
     _sb.Append("(");
     if (aggregate.Argument != null)
     {
         Visit(aggregate.Argument);
     }
     else if (aggregate.AggregateType == AggregateType.Count)
     {
         _sb.Append("*");
     }
     _sb.Append(")");
     return(aggregate);
 }
Exemplo n.º 16
0
        protected override Expression VisitAggregate(AggregateExpression aggregate)
        {
            string aggregateName = aggregate.AggregateName;

            if ((aggregateName != null) && (aggregateName == "Average"))
            {
                this.WriteTruncMaxDecimalDigitsStart();
                base.VisitAggregate(aggregate);
                this.WriteTruncMaxDecimalDigitsEnd();
            }
            else
            {
                return(base.VisitAggregate(aggregate));
            }
            return(aggregate);
        }
Exemplo n.º 17
0
        public void BindApplyWithCountInAggregateShouldReturnApplyClause()
        {
            IEnumerable <QueryToken> tokens = _parser.ParseApply("aggregate($count as TotalCount)");

            ApplyBinder binder = new ApplyBinder(FakeBindMethods.BindSingleComplexProperty, _bindingState);
            ApplyClause actual = binder.BindApply(tokens);

            Assert.NotNull(actual);
            AggregateTransformationNode aggregate = Assert.IsType <AggregateTransformationNode>(Assert.Single(actual.Transformations));

            Assert.Equal(TransformationNodeKind.Aggregate, aggregate.Kind);
            Assert.NotNull(aggregate.Expressions);
            AggregateExpression statement = Assert.Single(aggregate.Expressions);

            Assert.Equal(AggregationMethod.VirtualPropertyCount, statement.Method);
            Assert.Equal("TotalCount", statement.Alias);
        }
Exemplo n.º 18
0
        public virtual SqlFragment BuildAggregateSql(AggregateExpression expr)
        {
            if (expr.AggregateType == AggregateType.Count && expr.Operands.Count == 0)
            {
                return(this.SqlDialect.SqlCountStar);
            }
            SqlTemplate template = SqlDialect.GetAggregateTemplate(expr);

            if (template != null)
            {
                var args    = expr.GetOperands();
                var sqlArgs = args.Select(a => BuildLinqExpressionSql(a)).ToArray();
                return(template.Format(sqlArgs));
            }
            Util.Throw("Unsupported Aggregate type: {0}, expr: {1} ", expr.AggregateType, expr);
            return(null);
        }
Exemplo n.º 19
0
        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);
        }
Exemplo n.º 20
0
        public void BindApplyWithAggregateShouldReturnApplyClause()
        {
            IEnumerable <QueryToken> tokens = _parser.ParseApply("aggregate(UnitPrice with sum as TotalPrice)");

            ApplyBinder binder = new ApplyBinder(FakeBindMethods.BindSingleComplexProperty, _bindingState);
            ApplyClause actual = binder.BindApply(tokens);

            Assert.NotNull(actual);
            AggregateTransformationNode aggregate = Assert.IsType <AggregateTransformationNode>(Assert.Single(actual.Transformations));

            Assert.Equal(TransformationNodeKind.Aggregate, aggregate.Kind);
            Assert.NotNull(aggregate.AggregateExpressions);

            AggregateExpression statement = Assert.IsType <AggregateExpression>(Assert.Single(aggregate.AggregateExpressions));

            VerifyIsFakeSingleValueNode(statement.Expression);
            Assert.Equal(AggregationMethod.Sum, statement.Method);
            Assert.Equal("TotalPrice", statement.Alias);
        }
Exemplo n.º 21
0
 /// <summary>
 /// Visits the aggregate.
 /// </summary>
 /// <param name="aggregate">The aggregate.</param>
 /// <returns></returns>
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     this.WriteAggregateName(aggregate.AggregateName);
     this.Write("(");
     if (aggregate.IsDistinct)
     {
         this.Write("DISTINCT ");
     }
     if (aggregate.Argument != null)
     {
         this.VisitValue(aggregate.Argument);
     }
     else if (RequiresAsteriskWhenNoArgument(aggregate.AggregateName))
     {
         this.Write("*");
     }
     this.Write(")");
     return(aggregate);
 }
Exemplo n.º 22
0
        public void BindApplyWithAverageInAggregateShouldReturnApplyClause()
        {
            IEnumerable <QueryToken> tokens = _parser.ParseApply("aggregate(UnitPrice with average as AveragePrice)");

            ApplyBinder binder = new ApplyBinder(FakeBindMethods.BindMethodReturningASingleFloatPrimitive, _bindingState);
            ApplyClause actual = binder.BindApply(tokens);

            Assert.NotNull(actual);
            AggregateTransformationNode aggregate = Assert.IsType <AggregateTransformationNode>(Assert.Single(actual.Transformations));

            Assert.Equal(TransformationNodeKind.Aggregate, aggregate.Kind);
            Assert.NotNull(aggregate.AggregateExpressions);

            AggregateExpression statement = Assert.IsType <AggregateExpression>(Assert.Single(aggregate.AggregateExpressions));

            Assert.NotNull(statement.Expression);
            Assert.Same(FakeBindMethods.FakeSingleFloatPrimitive, statement.Expression);
            Assert.Equal(AggregationMethod.Average, statement.Method);
            Assert.Equal("AveragePrice", statement.Alias);
        }
Exemplo n.º 23
0
        public void BindVirtualPropertiesAfterCollapseReturnsApplyClause()
        {
            IEnumerable <QueryToken> tokens =
                _parser.ParseApply(
                    "groupby((ID))/aggregate($count as Count)");

            BindingState   state         = new BindingState(_configuration);
            MetadataBinder metadataBiner = new MetadataBinder(_bindingState);

            ApplyBinder binder = new ApplyBinder(metadataBiner.Bind, _bindingState);
            ApplyClause actual = binder.BindApply(tokens);

            Assert.NotNull(actual);
            Assert.Equal(2, actual.Transformations.Count());
            Assert.IsType <GroupByTransformationNode>(actual.Transformations.First());
            AggregateTransformationNode aggregate = Assert.IsType <AggregateTransformationNode>(actual.Transformations.Last());
            AggregateExpression         aggExp    = Assert.IsType <AggregateExpression>(Assert.Single(aggregate.AggregateExpressions));

            Assert.Equal(AggregationMethod.VirtualPropertyCount, aggExp.Method);
        }
Exemplo n.º 24
0
        public IActionResult Post(AggregateModel model)
        {
            var queryView = _queryViewFinder.FindById(model.QueryViewId);

            if (queryView == null)
            {
                return(NotFound());
            }
            if (queryView != null && queryView.AggregateConfig.IsNotEmpty())
            {
                var aggFields = new List <AggregateExpressionField>().DeserializeFromJson(queryView.AggregateConfig);
                if (aggFields.NotEmpty())
                {
                    var queryExp = new QueryExpression().DeserializeFromJson(queryView.FetchConfig);
                    if (model.Filter != null &&
                        (model.Filter.Conditions.NotEmpty() || (model.Filter.Filters.NotEmpty() && model.Filter.Filters.First().Conditions.NotEmpty())))
                    {
                        queryExp.Criteria.AddFilter(model.Filter);
                    }
                    var aggExp = new AggregateExpression
                    {
                        ColumnSet       = queryExp.ColumnSet,
                        Criteria        = queryExp.Criteria,
                        EntityName      = queryExp.EntityName,
                        LinkEntities    = queryExp.LinkEntities,
                        AggregateFields = aggFields
                    };
                    var aggDatas   = _aggregateService.Execute(aggExp);
                    var attributes = _attributeFinder.FindByName(queryView.EntityId, aggFields.Select(x => x.AttributeName).ToArray());
                    foreach (dynamic item in aggDatas)
                    {
                        var line      = item as IDictionary <string, object>;
                        var attribute = attributes.Find(x => x.Name.IsCaseInsensitiveEqual(line.Keys.First()));
                        item.metadata      = new { attribute.Name, attribute.LocalizedName, attribute.AttributeTypeName, attribute.EntityId, attribute.EntityName, attribute.EntityLocalizedName };
                        item.aggregatetype = aggFields.Find(x => x.AttributeName.IsCaseInsensitiveEqual(attribute.Name)).AggregateType;
                    }
                    return(JOk(new { View = new { queryView.QueryViewId, queryView.Name }, Data = aggDatas }));
                }
            }
            return(JOk());
        }
Exemplo n.º 25
0
        private MethodInfo GetCustomMethod(AggregateExpression expression)
        {
            var propertyLambda = Expression.Lambda(BindAccessor(expression.Expression), this._lambdaParameter);
            Type inputType = propertyLambda.Body.Type;

            string methodToken = expression.MethodDefinition.MethodLabel;
            var customFunctionAnnotations = Model.GetAnnotationValue<CustomAggregateMethodAnnotation>(Model);

            MethodInfo customMethod;
            if (!customFunctionAnnotations.GetMethodInfo(methodToken, inputType, out customMethod))
            {
                throw new ODataException(
                    Error.Format(
                        SRResources.AggregationNotSupportedForType,
                        expression.Method,
                        expression.Expression,
                        inputType));
            }

            return customMethod;
        }
Exemplo n.º 26
0
        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);
        }
Exemplo n.º 27
0
        public void BindApplyWithCountInAggregateShouldReturnApplyClause()
        {
            IEnumerable <QueryToken> tokens = _parser.ParseApply("aggregate($count as TotalCount)");

            ApplyBinder binder = new ApplyBinder(FakeBindMethods.BindSingleComplexProperty, _bindingState);
            ApplyClause actual = binder.BindApply(tokens);

            actual.Should().NotBeNull();
            actual.Transformations.Should().HaveCount(1);

            List <TransformationNode>   transformations = actual.Transformations.ToList();
            AggregateTransformationNode aggregate       = transformations[0] as AggregateTransformationNode;

            aggregate.Should().NotBeNull();
            aggregate.Kind.Should().Be(TransformationNodeKind.Aggregate);
            aggregate.Expressions.Should().NotBeNull();
            aggregate.Expressions.Should().HaveCount(1);

            List <AggregateExpression> statements = aggregate.Expressions.ToList();
            AggregateExpression        statement  = statements[0];

            statement.Method.Should().Be(AggregationMethod.VirtualPropertyCount);
            statement.Alias.Should().Be("TotalCount");
        }
Exemplo n.º 28
0
 /// <summary>
 /// This is a hacky function to convert condition which under aggregated node and operator is IsNull
 /// for normal query, if the condition is under aggregated node, the queryBuilder will add this condition to child aggregate table.
 /// however for IsNull condition is little special, it should be in main where clause and the condition node should be current aggreagate node id.
 /// </summary>
 /// <param name="conditions">structuredQuery conditions</param>
 /// <param name="aggregateEntity">current aggregated entity</param>
 private void ConvertConditionExpressionToAggregate(List <QueryCondition> conditions,
                                                    AggregateEntity aggregateEntity)
 {
     if (conditions.Any(c => c.Operator == ConditionType.IsNull &&
                        c.Expression is ResourceDataColumn &&
                        MatchGroupedEntityNode(((ResourceDataColumn)c.Expression).NodeId, aggregateEntity.GroupedEntity)
                        ))
     {
         foreach (QueryCondition condition in conditions)
         {
             ResourceDataColumn resourceExpression = condition.Expression as ResourceDataColumn;
             if (resourceExpression != null)
             {
                 AggregateExpression aggregateExpression = new AggregateExpression
                 {
                     AggregateMethod = AggregateMethod.Min,
                     NodeId          = aggregateEntity.NodeId,
                     Expression      = resourceExpression
                 };
                 condition.Expression = aggregateExpression;
             }
         }
     }
 }
Exemplo n.º 29
0
        public static object GetValue(this IAggregateService aggregateService, string entityName, FilterExpression filter, AggregateType aggregateType)
        {
            var agg = new AggregateExpression
            {
                EntityName = entityName
                ,
                AggregateFields = new List <AggregateExpressionField> {
                    new AggregateExpressionField {
                        AttributeName = entityName + "Id", AggregateType = aggregateType
                    }
                }
                ,
                Criteria = filter
            };

            agg.AddColumns(entityName + "Id");
            var values = aggregateService.Execute(agg);

            if (values.NotEmpty())
            {
                return((values[0] as IDictionary <string, object>).Values.First());
            }
            return(null);
        }
Exemplo n.º 30
0
        private Expression CreatePropertyAggregateExpression(ParameterExpression accum, AggregateExpression expression, Type baseType)
        {
            // accum type is IGrouping<,baseType> that implements IEnumerable<baseType>
            // we need cast it to IEnumerable<baseType> during expression building (IEnumerable)$it
            // however for EF6 we need to use $it.AsQueryable() due to limitations in types of casts that will properly translated
            Expression asQuerableExpression = null;

            if (_classicEF)
            {
                var asQuerableMethod = ExpressionHelperMethods.QueryableAsQueryable.MakeGenericMethod(baseType);
                asQuerableExpression = Expression.Call(null, asQuerableMethod, accum);
            }
            else
            {
                var queryableType = typeof(IEnumerable <>).MakeGenericType(baseType);
                asQuerableExpression = Expression.Convert(accum, queryableType);
            }

            // $count is a virtual property, so there's not a propertyLambda to create.
            if (expression.Method == AggregationMethod.VirtualPropertyCount)
            {
                var countMethod = (_classicEF
                    ? ExpressionHelperMethods.QueryableCountGeneric
                    : ExpressionHelperMethods.EnumerableCountGeneric).MakeGenericMethod(baseType);
                return(WrapConvert(Expression.Call(null, countMethod, asQuerableExpression)));
            }

            Expression body;

            var lambdaParameter = baseType == this._elementType ? this._lambdaParameter : Expression.Parameter(baseType, "$it");

            if (!this._preFlattenedMap.TryGetValue(expression.Expression, out body))
            {
                body = BindAccessor(expression.Expression, lambdaParameter);
            }
            LambdaExpression propertyLambda = Expression.Lambda(body, lambdaParameter);

            Expression aggregationExpression;

            switch (expression.Method)
            {
            case AggregationMethod.Min:
            {
                var minMethod = (_classicEF
                            ? ExpressionHelperMethods.QueryableMin
                            : ExpressionHelperMethods.EnumerableMin).MakeGenericMethod(baseType,
                                                                                       propertyLambda.Body.Type);
                aggregationExpression = Expression.Call(null, minMethod, asQuerableExpression, propertyLambda);
            }
            break;

            case AggregationMethod.Max:
            {
                var maxMethod = (_classicEF
                            ? ExpressionHelperMethods.QueryableMax
                            : ExpressionHelperMethods.EnumerableMax).MakeGenericMethod(baseType,
                                                                                       propertyLambda.Body.Type);
                aggregationExpression = Expression.Call(null, maxMethod, asQuerableExpression, propertyLambda);
            }
            break;

            case AggregationMethod.Sum:
            {
                MethodInfo sumGenericMethod;
                // For Dynamic properties cast to decimal
                Expression propertyExpression = WrapDynamicCastIfNeeded(body);
                propertyLambda = Expression.Lambda(propertyExpression, lambdaParameter);

                if (
                    !(_classicEF
                                ? ExpressionHelperMethods.QueryableSumGenerics
                                : ExpressionHelperMethods.EnumerableSumGenerics).TryGetValue(propertyExpression.Type,
                                                                                             out sumGenericMethod))
                {
                    throw new ODataException(Error.Format(SRResources.AggregationNotSupportedForType,
                                                          expression.Method, expression.Expression, propertyExpression.Type));
                }

                var sumMethod = sumGenericMethod.MakeGenericMethod(baseType);
                aggregationExpression = Expression.Call(null, sumMethod, asQuerableExpression, propertyLambda);

                // For Dynamic properties cast back to object
                if (propertyLambda.Type == typeof(object))
                {
                    aggregationExpression = Expression.Convert(aggregationExpression, typeof(object));
                }
            }
            break;

            case AggregationMethod.Average:
            {
                MethodInfo averageGenericMethod;
                // For Dynamic properties cast to decimal
                Expression propertyExpression = WrapDynamicCastIfNeeded(body);
                propertyLambda = Expression.Lambda(propertyExpression, lambdaParameter);

                if (
                    !(_classicEF
                                ? ExpressionHelperMethods.QueryableAverageGenerics
                                : ExpressionHelperMethods.EnumerableAverageGenerics).TryGetValue(propertyExpression.Type,
                                                                                                 out averageGenericMethod))
                {
                    throw new ODataException(Error.Format(SRResources.AggregationNotSupportedForType,
                                                          expression.Method, expression.Expression, propertyExpression.Type));
                }

                var averageMethod = averageGenericMethod.MakeGenericMethod(baseType);
                aggregationExpression = Expression.Call(null, averageMethod, asQuerableExpression, propertyLambda);

                // For Dynamic properties cast back to object
                if (propertyLambda.Type == typeof(object))
                {
                    aggregationExpression = Expression.Convert(aggregationExpression, typeof(object));
                }
            }
            break;

            case AggregationMethod.CountDistinct:
            {
                // I select the specific field
                var selectMethod =
                    (_classicEF
                                ? ExpressionHelperMethods.QueryableSelectGeneric
                                : ExpressionHelperMethods.EnumerableSelectGeneric).MakeGenericMethod(this._elementType,
                                                                                                     propertyLambda.Body.Type);
                Expression queryableSelectExpression = Expression.Call(null, selectMethod, asQuerableExpression,
                                                                       propertyLambda);

                // I run distinct over the set of items
                var distinctMethod =
                    (_classicEF
                                ? ExpressionHelperMethods.QueryableDistinct
                                : ExpressionHelperMethods.EnumerableDistinct).MakeGenericMethod(propertyLambda.Body.Type);
                Expression distinctExpression = Expression.Call(null, distinctMethod, queryableSelectExpression);

                // I count the distinct items as the aggregation expression
                var countMethod =
                    (_classicEF
                                ? ExpressionHelperMethods.QueryableCountGeneric
                                : ExpressionHelperMethods.EnumerableCountGeneric).MakeGenericMethod(propertyLambda.Body.Type);
                aggregationExpression = Expression.Call(null, countMethod, distinctExpression);
            }
            break;

            case AggregationMethod.Custom:
            {
                MethodInfo customMethod = GetCustomMethod(expression);
                var        selectMethod =
                    (_classicEF
                                ? ExpressionHelperMethods.QueryableSelectGeneric
                                : ExpressionHelperMethods.EnumerableSelectGeneric).MakeGenericMethod(this._elementType, propertyLambda.Body.Type);
                var selectExpression = Expression.Call(null, selectMethod, asQuerableExpression, propertyLambda);
                aggregationExpression = Expression.Call(null, customMethod, selectExpression);
            }
            break;

            default:
                throw new ODataException(Error.Format(SRResources.AggregationMethodNotSupported, expression.Method));
            }

            return(WrapConvert(aggregationExpression));
        }
        /// <summary>
        /// Query for a single value.
        /// </summary>
        private static async Task Aggregate(RDXOeeKpiQuery rdxQuery, ContosoOpcUaNode opcUaNode, AggregateExpression expression)
        {
            opcUaNode.Last.Value = await rdxQuery.OpcUaQueries.GetAggregatedNode(rdxQuery.SearchSpan, rdxQuery.AppUri, opcUaNode.NodeId, expression);

            opcUaNode.Last.Time = rdxQuery.SearchSpan.To;
            opcUaNode.UpdateRelevance(rdxQuery.TopologyNode);
        }
Exemplo n.º 32
0
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     this.hasAggregate = true;
     return aggregate;
 }
Exemplo n.º 33
0
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     sb.Append(GetAggregateName(aggregate.AggregateType));
     sb.Append("(");
     if (aggregate.IsDistinct)
     {
         sb.Append("DISTINCT ");
     }
     if (aggregate.Argument != null)
     {
         VisitValue(aggregate.Argument);
     }
     else if (RequiresAsteriskWhenNoArgument(aggregate.AggregateType))
     {
         sb.Append("*");
     }
     sb.Append(")");
     return aggregate;
 }
Exemplo n.º 34
0
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     Expression source = MakeSqlValue(Visit(aggregate.Source));
     if (source != aggregate.Source)
         return new AggregateExpression(aggregate.Type, source, aggregate.AggregateFunction);
     return aggregate;
 }
Exemplo n.º 35
0
 protected virtual bool CompareAggregate(AggregateExpression a, AggregateExpression b)
 {
     return a.AggregateName == b.AggregateName && this.Compare(a.Argument, b.Argument);
 }
Exemplo n.º 36
0
 protected virtual Expression VisitAggregate(AggregateExpression aggregate)
 {
     var arg = this.Visit(aggregate.Argument);
     return this.UpdateAggregate(aggregate, aggregate.Type, aggregate.AggregateName, arg, aggregate.IsDistinct);
 }
Exemplo n.º 37
0
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     hasAggregates = true;
     return base.VisitAggregate(aggregate);
 }
		private bool CompareAggregate(AggregateExpression a, AggregateExpression b)
		{
			return a.AggregateName == b.AggregateName && this.Compare(a.Argument, b.Argument);
		}
Exemplo n.º 39
0
        private Expression BindAggregate(Expression source, MethodInfo method, LambdaExpression argument, bool isRoot)
        {
            Type          returnType           = method.ReturnType;
            AggregateType aggType              = GetAggregateType(method.Name);
            bool          hasPredicateArg      = HasPredicateArg(aggType);
            bool          isDistinct           = false;
            bool          argumentWasPredicate = false;
            bool          useAlternateArg      = false;

            // check for distinct
            MethodCallExpression mcs = source as MethodCallExpression;

            if (mcs != null && !hasPredicateArg && argument == null)
            {
                if (mcs.Method.Name == "Distinct" && mcs.Arguments.Count == 1 &&
                    (mcs.Method.DeclaringType == typeof(Queryable) || mcs.Method.DeclaringType == typeof(Enumerable)))
                {
                    source     = mcs.Arguments[0];
                    isDistinct = true;
                }
            }

            if (argument != null && hasPredicateArg)
            {
                // convert query.Count(predicate) into query.Where(predicate).Count()
                source               = Expression.Call(typeof(Queryable), "Where", method.GetGenericArguments(), source, argument);
                argument             = null;
                argumentWasPredicate = true;
            }

            ProjectionExpression projection = VisitSequence(source);

            Expression argExpr = null;

            if (argument != null)
            {
                map[argument.Parameters[0]] = projection.Projector;
                argExpr = Visit(argument.Body);
            }
            else if (!hasPredicateArg || useAlternateArg)
            {
                argExpr = projection.Projector;
            }

            var              alias   = GetNextAlias();
            var              pc      = ProjectColumns(projection.Projector, alias, projection.Source.Alias);
            Expression       aggExpr = new AggregateExpression(returnType, aggType, argExpr, isDistinct);
            SelectExpression select  = new SelectExpression(alias, new[] { new ColumnDeclaration("", aggExpr) },
                                                            projection.Source, null);

            if (isRoot)
            {
                ParameterExpression p     = Expression.Parameter(typeof(IEnumerable <>).MakeGenericType(aggExpr.Type), "p");
                LambdaExpression    gator =
                    Expression.Lambda(Expression.Call(typeof(Enumerable), "Single", new[] { returnType }, p), p);
                return(new ProjectionExpression(select, new ColumnExpression(returnType, alias, ""), gator));
            }

            ScalarExpression subquery = new ScalarExpression(returnType, select);

            // if we can find the corresponding group-info we can build a special AggregateSubquery node that will enable us to
            // optimize the aggregate expression later using AggregateRewriter
            GroupByInfo info;

            if (!argumentWasPredicate && groupByMap.TryGetValue(projection, out info))
            {
                // use the element expression from the group-by info to rebind the argument so the resulting expression is one that
                // would be legal to add to the columns in the select expression that has the corresponding group-by clause.
                if (argument != null)
                {
                    map[argument.Parameters[0]] = info.Element;
                    argExpr = Visit(argument.Body);
                }
                else if (!hasPredicateArg || useAlternateArg)
                {
                    argExpr = info.Element;
                }
                aggExpr = new AggregateExpression(returnType, aggType, argExpr, isDistinct);

                // check for easy to optimize case.  If the projection that our aggregate is based on is really the 'group' argument from
                // the query.GroupBy(xxx, (key, group) => yyy) method then whatever expression we return here will automatically
                // become part of the select expression that has the group-by clause, so just return the simple aggregate expression.
                if (projection == currentGroupElement)
                {
                    return(aggExpr);
                }

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

            return(subquery);
        }
Exemplo n.º 40
0
        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);
        }
Exemplo n.º 41
0
 protected virtual bool CompareAggregate(AggregateExpression a, AggregateExpression b)
 {
     return(a.AggregateType == b.AggregateType && Compare(a.Argument, b.Argument));
 }
Exemplo n.º 42
0
 protected virtual Expression VisitAggregate(AggregateExpression aggregate)
 {
     Expression source = Visit(aggregate.Source);
     if (source != aggregate.Source)
         return new AggregateExpression(aggregate.Type, source, aggregate.AggregateFunction);
     return aggregate;
 }
Exemplo n.º 43
0
 protected override Expression VisitAggregate(AggregateExpression aggregate)
 {
     this.WriteAggregateName(aggregate.AggregateName);
     this.Write("(");
     if (aggregate.IsDistinct)
     {
         this.Write("DISTINCT ");
     }
     if (aggregate.Argument != null)
     {
         this.VisitValue(aggregate.Argument);
     }
     else if (RequiresAsteriskWhenNoArgument(aggregate.AggregateName))
     {
         this.Write("*");
     }
     this.Write(")");
     return aggregate;
 }
Exemplo n.º 44
0
        private Expression BindAggregate(Expression source, string aggName, Type returnType, LambdaExpression argument, bool isRoot)
        {
            bool hasPredicateArg = this.language.AggregateArgumentIsPredicate(aggName);
            bool isDistinct = false;
            bool argumentWasPredicate = false;
            bool useAlternateArg = false;

            // check for distinct
            MethodCallExpression mcs = source as MethodCallExpression;
            if (mcs != null && !hasPredicateArg && argument == null)
            {
                if (mcs.Method.Name == "Distinct" && mcs.Arguments.Count == 1 &&
                    (mcs.Method.DeclaringType == typeof(Queryable) || mcs.Method.DeclaringType == typeof(Enumerable))
                    && this.language.AllowDistinctInAggregates)
                {
                    source = mcs.Arguments[0];
                    isDistinct = true;
                }
            }

            if (argument != null && hasPredicateArg)
            {
                // convert query.Count(predicate) into query.Where(predicate).Count()
                source = Expression.Call(typeof(Queryable), "Where", new[] { TypeHelper.GetElementType(source.Type) }, source, argument);
                argument = null;
                argumentWasPredicate = true;
            }

            ProjectionExpression projection = this.VisitSequence(source);

            Expression argExpr = null;
            if (argument != null)
            {
                this.map[argument.Parameters[0]] = projection.Projector;
                argExpr = this.Visit(argument.Body);
            }
            else if (!hasPredicateArg || useAlternateArg)
            {
                argExpr = projection.Projector;
            }

            var alias = this.GetNextAlias();
            var pc = this.ProjectColumns(projection.Projector, alias, projection.Select.Alias);
            Expression aggExpr = new AggregateExpression(returnType, aggName, argExpr, isDistinct);
            var colType = this.language.TypeSystem.GetColumnType(returnType);
            SelectExpression select = new SelectExpression(alias, new ColumnDeclaration[] { new ColumnDeclaration("", aggExpr, colType) }, projection.Select, null);

            if (isRoot)
            {
                ParameterExpression p = Expression.Parameter(typeof(IEnumerable<>).MakeGenericType(aggExpr.Type), "p");
                LambdaExpression gator = Expression.Lambda(Expression.Call(typeof(Enumerable), "Single", new Type[] { returnType }, p), p);
                return new ProjectionExpression(select, new ColumnExpression(returnType, this.language.TypeSystem.GetColumnType(returnType), alias, ""), gator);
            }

            ScalarExpression subquery = new ScalarExpression(returnType, select);

            // if we can find the corresponding group-info we can build a special AggregateSubquery node that will enable us to 
            // optimize the aggregate expression later using AggregateRewriter
            GroupByInfo info;
            if (!argumentWasPredicate && this.groupByMap.TryGetValue(projection, out info))
            {
                // use the element expression from the group-by info to rebind the argument so the resulting expression is one that 
                // would be legal to add to the columns in the select expression that has the corresponding group-by clause.
                if (argument != null)
                {
                    this.map[argument.Parameters[0]] = info.Element;
                    argExpr = this.Visit(argument.Body);
                }
                else if (!hasPredicateArg || useAlternateArg)
                {
                    argExpr = info.Element;
                }
                aggExpr = new AggregateExpression(returnType, aggName, argExpr, isDistinct);

                // check for easy to optimize case.  If the projection that our aggregate is based on is really the 'group' argument from
                // the query.GroupBy(xxx, (key, group) => yyy) method then whatever expression we return here will automatically
                // become part of the select expression that has the group-by clause, so just return the simple aggregate expression.
                if (projection == this.currentGroupElement)
                    return aggExpr;

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

            return subquery;
        }
Exemplo n.º 45
0
        private Expression CreateAggregationExpression(ParameterExpression accum, AggregateExpression expression)
        {
            // I substitute the element type for all generic arguments.
            var        asQuerableMethod     = ExpressionHelperMethods.QueryableAsQueryable.MakeGenericMethod(this._elementType);
            Expression asQuerableExpression = Expression.Call(null, asQuerableMethod, accum);

            // $count is a virtual property, so there's not a propertyLambda to create.
            if (expression.Method == AggregationMethod.VirtualPropertyCount)
            {
                var countMethod = ExpressionHelperMethods.QueryableCountGeneric.MakeGenericMethod(this._elementType);
                return(this.WrapConvert(Expression.Call(null, countMethod, asQuerableExpression)));
            }

            LambdaExpression propertyLambda = Expression.Lambda(this.BindAccessor(expression.Expression), this._lambdaParameter);

            Expression aggregationExpression;

            switch (expression.Method)
            {
            case AggregationMethod.Min:
            {
                var minMethod = ExpressionHelperMethods.QueryableMin.MakeGenericMethod(this._elementType,
                                                                                       propertyLambda.Body.Type);
                aggregationExpression = Expression.Call(null, minMethod, asQuerableExpression, propertyLambda);
            }
            break;

            case AggregationMethod.Max:
            {
                var maxMethod = ExpressionHelperMethods.QueryableMax.MakeGenericMethod(this._elementType,
                                                                                       propertyLambda.Body.Type);
                aggregationExpression = Expression.Call(null, maxMethod, asQuerableExpression, propertyLambda);
            }
            break;

            case AggregationMethod.Sum:
            {
                MethodInfo sumGenericMethod;
                if (
                    !ExpressionHelperMethods.QueryableSumGenerics.TryGetValue(propertyLambda.Body.Type,
                                                                              out sumGenericMethod))
                {
                    throw new ODataException(Error.Format(SRResources.AggregationNotSupportedForType,
                                                          expression.Method, expression.Expression, propertyLambda.Body.Type));
                }
                var sumMethod = sumGenericMethod.MakeGenericMethod(this._elementType);
                aggregationExpression = Expression.Call(null, sumMethod, asQuerableExpression, propertyLambda);
            }
            break;

            case AggregationMethod.Average:
            {
                MethodInfo averageGenericMethod;
                if (
                    !ExpressionHelperMethods.QueryableAverageGenerics.TryGetValue(propertyLambda.Body.Type,
                                                                                  out averageGenericMethod))
                {
                    throw new ODataException(Error.Format(SRResources.AggregationNotSupportedForType,
                                                          expression.Method, expression.Expression, propertyLambda.Body.Type));
                }
                var averageMethod = averageGenericMethod.MakeGenericMethod(this._elementType);
                aggregationExpression = Expression.Call(null, averageMethod, asQuerableExpression, propertyLambda);
            }
            break;

            case AggregationMethod.CountDistinct:
            {
                // I select the specific field
                var selectMethod =
                    ExpressionHelperMethods.QueryableSelectGeneric.MakeGenericMethod(this._elementType,
                                                                                     propertyLambda.Body.Type);
                Expression queryableSelectExpression = Expression.Call(null, selectMethod, asQuerableExpression,
                                                                       propertyLambda);

                // I run distinct over the set of items
                var distinctMethod =
                    ExpressionHelperMethods.QueryableDistinct.MakeGenericMethod(propertyLambda.Body.Type);
                Expression distinctExpression = Expression.Call(null, distinctMethod, queryableSelectExpression);

                // I count the distinct items as the aggregation expression
                var countMethod =
                    ExpressionHelperMethods.QueryableCountGeneric.MakeGenericMethod(propertyLambda.Body.Type);
                aggregationExpression = Expression.Call(null, countMethod, distinctExpression);
            }
            break;

            case AggregationMethod.Custom:
            {
                MethodInfo customMethod = this.GetCustomMethod(expression);
                var        selectMethod =
                    ExpressionHelperMethods.QueryableSelectGeneric.MakeGenericMethod(this._elementType, propertyLambda.Body.Type);
                var selectExpression = Expression.Call(null, selectMethod, asQuerableExpression, propertyLambda);
                aggregationExpression = Expression.Call(null, customMethod, selectExpression);
            }
            break;

            default:
                throw new ODataException(Error.Format(SRResources.AggregationMethodNotSupported, expression.Method));
            }

            return(this.WrapConvert(aggregationExpression));
        }
Exemplo n.º 46
0
        protected override Expression VisitAggregate(AggregateExpression aggregate)
        {
            sb.Append(dic[aggregate.AggregateFunction]);
            sb.Append("(");
            if (aggregate.Source == null)
                sb.Append("*");
            else
                Visit(aggregate.Source);
            sb.Append(")");

            return aggregate; 
        }