Пример #1
0
        /// <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());
        }