/// <summary> /// Constructs a $apply aggregate transformation. /// E.g. $apply=aggregate(Prop with sum as SumProp, Prop with average as AverageProp) /// </summary> /// <param name="aggregations">List of aggregations.</param> /// <returns>The aggregate tranformation.</returns> private string ConstructAggregateTransformation(IList <ApplyQueryOptionExpression.Aggregation> aggregations) { StringBuilder aggregateBuilder = new StringBuilder(); aggregateBuilder.Append(UriHelper.AGGREGATE); aggregateBuilder.Append(UriHelper.LEFTPAREN); int i = 0; while (true) { ApplyQueryOptionExpression.Aggregation aggregation = aggregations[i]; AggregationMethod aggregationMethod = aggregation.AggregationMethod; string aggregationAlias = aggregation.AggregationAlias; string aggregationUriEquivalent; if (!TypeSystem.TryGetUriEquivalent(aggregationMethod, out aggregationUriEquivalent)) { // This would happen if an aggregation method was added to the enum with no // relevant update to map it to the URI equivalent throw new NotSupportedException(Strings.ALinq_AggregationMethodNotSupported(aggregationMethod.ToString())); } string aggregationProperty = string.Empty; // E.g. Amount with sum as SumAmount (For $count aggregation: $count as Count) if (aggregationMethod != AggregationMethod.VirtualPropertyCount) { aggregationProperty = this.ExpressionToString(aggregation.Expression, /*inPath*/ false); aggregateBuilder.Append(aggregationProperty); aggregateBuilder.Append(UriHelper.SPACE); aggregateBuilder.Append(UriHelper.WITH); aggregateBuilder.Append(UriHelper.SPACE); } aggregateBuilder.Append(aggregationUriEquivalent); aggregateBuilder.Append(UriHelper.SPACE); aggregateBuilder.Append(UriHelper.AS); aggregateBuilder.Append(UriHelper.SPACE); // MUST define an alias for the resulting aggregate value // Concatenate aggregation method with aggregation property to generate a simple identifier/alias // OASIS Standard: The alias MUST NOT collide with names of declared properties, custom aggregates, or other aliases in that type // TODO: Strategy to avoid name collision - Append a Guid? if (string.IsNullOrEmpty(aggregationAlias)) { aggregationAlias = aggregationMethod.ToString() + aggregationProperty.Replace('/', '_'); } aggregateBuilder.Append(aggregationAlias); if (++i == aggregations.Count) { break; } aggregateBuilder.Append(UriHelper.COMMA); } aggregateBuilder.Append(UriHelper.RIGHTPAREN); return(aggregateBuilder.ToString()); }