public void ParseApplyWithNestedAggregation() { string apply = "groupby((UnitPrice), aggregate(Sales($count as Count)))"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(1); List <QueryToken> transformations = actual.ToList(); // verify groupby GroupByToken groupBy = transformations[0] as GroupByToken; groupBy.Should().NotBeNull(); VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy); groupBy.Properties.Should().HaveCount(1); groupBy.Child.Should().NotBeNull(); AggregateToken groupByAggregate = groupBy.Child as AggregateToken; groupByAggregate.AggregateExpressions.Should().HaveCount(1); EntitySetAggregateToken entitySetAggregate = groupByAggregate.AggregateExpressions.First() as EntitySetAggregateToken; entitySetAggregate.Should().NotBeNull(); entitySetAggregate.EntitySet.ShouldBeEndPathToken("Sales"); VerifyAggregateExpressionToken("$count", AggregationMethodDefinition.VirtualPropertyCount, "Count", entitySetAggregate.Expressions.First() as AggregateExpressionToken); }
public void NestedGroupbyTransformationsIsAllowed() { var result = this.ParseExpandOptions("($apply=groupby((Customer/CountryRegion,Product/Name),aggregate(Amount with sum as Total)))"); result.Should().NotBeNull(); QueryToken token = result.ApplyOptions.Single(); token.Should().BeOfType <GroupByToken>(); GroupByToken groupBy = token as GroupByToken; groupBy.Properties.Should().HaveCount(2); QueryToken queryToken = groupBy.Properties.ElementAt(0); EndPathToken pathToken = queryToken.ShouldBeEndPathToken("CountryRegion"); pathToken.NextToken.ShouldBeInnerPathToken("Customer"); queryToken = groupBy.Properties.ElementAt(1); pathToken = queryToken.ShouldBeEndPathToken("Name"); pathToken.NextToken.ShouldBeInnerPathToken("Product"); groupBy.Child.Should().NotBeNull(); groupBy.Child.Should().BeOfType <AggregateToken>(); AggregateToken aggregate = groupBy.Child as AggregateToken; AggregateExpressionToken aggregateExpressionToken = aggregate.Expressions.Single(); aggregateExpressionToken.Alias.Should().Equals("Total"); aggregateExpressionToken.Method.Should().Equals(AggregationMethod.Sum); aggregateExpressionToken.Expression.ShouldBeEndPathToken("Amount"); }
static Expression BuildAggregateExpression(Expression collection, AggregateToken at, BuildExpressionContext context) { Type groupType = collection.Type.GetGenericInterfaces(typeof(IEnumerable <>)).SingleEx(() => "IEnumerable<T> implementations on {0}".FormatWith(collection.Type)).GetGenericArguments()[0]; if (at.AggregateFunction == Signum.Entities.DynamicQuery.AggregateFunction.Count) { return(Expression.Call(typeof(Enumerable), "Count", new[] { groupType }, new[] { collection })); } var body = at.Parent.BuildExpression(context); var type = at.Type; if (body.Type != type) { body = body.TryConvert(type); } var lambda = Expression.Lambda(body, context.Parameter); if (at.AggregateFunction == Signum.Entities.DynamicQuery.AggregateFunction.Min || at.AggregateFunction == Signum.Entities.DynamicQuery.AggregateFunction.Max) { return(Expression.Call(typeof(Enumerable), at.AggregateFunction.ToString(), new[] { groupType, lambda.Body.Type }, new[] { collection, lambda })); } return(Expression.Call(typeof(Enumerable), at.AggregateFunction.ToString(), new[] { groupType }, new[] { collection, lambda })); }
public void NestedGroupbyTransformationsInExpandIsAllowed() { // Arrange & Act ExpandTermToken expandTerm = this.ParseExpandOptions("($apply=groupby((Customer/CountryRegion,Product/Name),aggregate(Amount with sum as Total)))"); // Assert Assert.NotNull(expandTerm); Assert.NotNull(expandTerm.ApplyOptions); QueryToken token = Assert.Single(expandTerm.ApplyOptions); GroupByToken groupBy = Assert.IsType <GroupByToken>(token); Assert.Equal(2, groupBy.Properties.Count()); QueryToken queryToken = groupBy.Properties.ElementAt(0); EndPathToken pathToken = queryToken.ShouldBeEndPathToken("CountryRegion"); pathToken.NextToken.ShouldBeInnerPathToken("Customer"); queryToken = groupBy.Properties.ElementAt(1); pathToken = queryToken.ShouldBeEndPathToken("Name"); pathToken.NextToken.ShouldBeInnerPathToken("Product"); Assert.NotNull(groupBy.Child); AggregateToken aggregate = Assert.IsType <AggregateToken>(groupBy.Child); AggregateExpressionToken aggregateExpressionToken = Assert.Single(aggregate.Expressions); Assert.Equal("Total", aggregateExpressionToken.Alias); Assert.Equal(AggregationMethod.Sum, aggregateExpressionToken.Method); aggregateExpressionToken.Expression.ShouldBeEndPathToken("Amount"); }
private AggregateTransformationNode BindAggregateToken(AggregateToken token) { var statements = new List<AggregateStatement>(); foreach (var statementToken in token.Statements) { statements.Add(BindAggregateStatementToken(statementToken)); } return new AggregateTransformationNode(statements); }
private AggregateTransformationNode BindAggregateToken(AggregateToken token) { var statements = new List <AggregateStatement>(); foreach (var statementToken in token.Statements) { statements.Add(BindAggregateStatementToken(statementToken)); } return(new AggregateTransformationNode(statements)); }
public void ParseApplyWithSingleAggregateExpressionShouldReturnAggregateToken() { string apply = "aggregate(UnitPrice with sum as TotalPrice)"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); Assert.NotNull(actual); var token = Assert.Single(actual); AggregateToken aggregate = Assert.IsType <AggregateToken>(token); var aggregateExpr = Assert.Single(aggregate.AggregateExpressions); VerifyAggregateExpressionToken("UnitPrice", AggregationMethodDefinition.Sum, "TotalPrice", aggregateExpr as AggregateExpressionToken); }
public void ParseApplyWithDottedUnkownExpressionShouldReturnCustomAggregateToken() { string apply = "aggregate(UnitPrice with Custom.Aggregate as CustomAggregate)"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(1); AggregateToken aggregate = actual.First() as AggregateToken; aggregate.Should().NotBeNull(); aggregate.AggregateExpressions.Should().HaveCount(1); VerifyAggregateExpressionToken("UnitPrice", AggregationMethodDefinition.Custom("Custom.Aggregate"), "CustomAggregate", aggregate.AggregateExpressions.First() as AggregateExpressionToken); }
public void NestedAggregateTransformationIsAllowed() { var result = this.ParseExpandOptions("($apply=aggregate(Amount with sum as Total))"); result.Should().NotBeNull(); QueryToken token = result.ApplyOptions.Single(); token.Should().BeOfType <AggregateToken>(); AggregateToken aggregate = token as AggregateToken; AggregateExpressionToken aggregateExpressionToken = aggregate.Expressions.Single(); aggregateExpressionToken.Alias.Should().Equals("Total"); aggregateExpressionToken.Method.Should().Equals(AggregationMethod.Sum); aggregateExpressionToken.Expression.ShouldBeEndPathToken("Amount"); }
public void ParseApplyWithSingleCountExpressionShouldReturnAggregateToken() { string apply = "aggregate($count as Count)"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(1); AggregateToken aggregate = actual.First() as AggregateToken; aggregate.Should().NotBeNull(); aggregate.AggregateExpressions.Should().HaveCount(1); VerifyAggregateExpressionToken("$count", AggregationMethodDefinition.VirtualPropertyCount, "Count", aggregate.AggregateExpressions.First() as AggregateExpressionToken); }
public void ParseApplyWithSingleAggregateExpressionShouldReturnAggregateToken() { string apply = "aggregate(UnitPrice with sum as TotalPrice)"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(1); AggregateToken aggregate = actual.First() as AggregateToken; aggregate.Should().NotBeNull(); aggregate.AggregateExpressions.Should().HaveCount(1); VerifyAggregateExpressionToken("UnitPrice", AggregationMethodDefinition.Sum, "TotalPrice", aggregate.AggregateExpressions.First() as AggregateExpressionToken); }
public void NestedAggregateTransformationInExpandIsAllowed() { // Arrange & Act ExpandTermToken expandTerm = this.ParseExpandOptions("($apply=aggregate(Amount with sum as Total))"); // Assert Assert.NotNull(expandTerm); Assert.NotNull(expandTerm.ApplyOptions); QueryToken token = Assert.Single(expandTerm.ApplyOptions); AggregateToken aggregate = Assert.IsType <AggregateToken>(token); AggregateExpressionToken aggregateExpressionToken = Assert.Single(aggregate.Expressions); Assert.Equal("Total", aggregateExpressionToken.Alias); Assert.Equal(AggregationMethod.Sum, aggregateExpressionToken.Method); aggregateExpressionToken.Expression.ShouldBeEndPathToken("Amount"); }
public void ParseApplyWithNestedFunctionAggregation() { string apply = "groupby((UnitPrice), aggregate(Sales($count as Count, cast(SalesPrice, Edm.Decimal) with average as RetailPrice)))"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(1); List <QueryToken> transformations = actual.ToList(); // verify groupby GroupByToken groupBy = transformations[0] as GroupByToken; groupBy.Should().NotBeNull(); VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy); groupBy.Properties.Should().HaveCount(1); groupBy.Child.Should().NotBeNull(); AggregateToken groupByAggregate = groupBy.Child as AggregateToken; groupByAggregate.AggregateExpressions.Should().HaveCount(1); EntitySetAggregateToken entitySetAggregate = groupByAggregate.AggregateExpressions.First() as EntitySetAggregateToken; entitySetAggregate.Should().NotBeNull(); entitySetAggregate.EntitySet.ShouldBeEndPathToken("Sales"); entitySetAggregate.Expressions.Should().HaveCount(2); VerifyAggregateExpressionToken("$count", AggregationMethodDefinition.VirtualPropertyCount, "Count", entitySetAggregate.Expressions.First() as AggregateExpressionToken); AggregateExpressionToken funcAggregate = entitySetAggregate.Expressions.Last() as AggregateExpressionToken; funcAggregate.Should().NotBeNull(); funcAggregate.Alias.ShouldBeEquivalentTo("RetailPrice"); funcAggregate.Method.Should().Equals(AggregationMethodDefinition.Average); FunctionCallToken funcToken = funcAggregate.Expression as FunctionCallToken; funcToken.Should().NotBeNull(); funcToken.Name.ShouldBeEquivalentTo("cast"); }
public void ParseApplyWithMultipleAggregateExpressionsShouldReturnAggregateTokens() { string apply = "aggregate(CustomerId with sum as Total, SharePrice with countdistinct as SharePriceDistinctCount)"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(1); AggregateToken aggregate = actual.First() as AggregateToken; aggregate.Should().NotBeNull(); aggregate.AggregateExpressions.Should().HaveCount(2); List <AggregateTokenBase> statements = aggregate.AggregateExpressions.ToList(); VerifyAggregateExpressionToken("CustomerId", AggregationMethodDefinition.Sum, "Total", statements[0] as AggregateExpressionToken); VerifyAggregateExpressionToken("SharePrice", AggregationMethodDefinition.CountDistinct, "SharePriceDistinctCount", statements[1] as AggregateExpressionToken); }
public void ParseApplyWithNestedAggregationAndFunction() { string apply = "groupby((UnitPrice), aggregate(Sales($count as Count), cast(SalesPrice, Edm.Decimal) with average as RetailPrice))"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); Assert.NotNull(actual); Assert.Single(actual); List <QueryToken> transformations = actual.ToList(); // verify groupby GroupByToken groupBy = transformations[0] as GroupByToken; Assert.NotNull(groupBy); VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy); Assert.Single(groupBy.Properties); Assert.NotNull(groupBy.Child); AggregateToken groupByAggregate = groupBy.Child as AggregateToken; Assert.Equal(2, groupByAggregate.AggregateExpressions.Count()); EntitySetAggregateToken entitySetAggregate = groupByAggregate.AggregateExpressions.First() as EntitySetAggregateToken; Assert.NotNull(entitySetAggregate); entitySetAggregate.EntitySet.ShouldBeEndPathToken("Sales"); VerifyAggregateExpressionToken("$count", AggregationMethodDefinition.VirtualPropertyCount, "Count", entitySetAggregate.Expressions.First() as AggregateExpressionToken); AggregateExpressionToken funcAggregate = groupByAggregate.AggregateExpressions.Last() as AggregateExpressionToken; Assert.NotNull(funcAggregate); Assert.Equal("RetailPrice", funcAggregate.Alias); Assert.Equal(AggregationMethod.Average, funcAggregate.Method); FunctionCallToken funcToken = funcAggregate.Expression as FunctionCallToken; Assert.NotNull(funcToken); Assert.Equal("cast", funcToken.Name); }
public void ParseApplyWithCountAndOtherAggregationExpressionShouldReturnAggregateToken() { string apply = "aggregate($count as Count, SharePrice with countdistinct as SharePriceDistinctCount)"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(1); AggregateToken aggregate = actual.First() as AggregateToken; aggregate.Should().NotBeNull(); aggregate.AggregateExpressions.Should().HaveCount(2); List <AggregateTokenBase> statements = aggregate.AggregateExpressions.ToList(); VerifyAggregateExpressionToken("$count", AggregationMethodDefinition.VirtualPropertyCount, "Count", aggregate.AggregateExpressions.First() as AggregateExpressionToken); VerifyAggregateExpressionToken("SharePrice", AggregationMethodDefinition.CountDistinct, "SharePriceDistinctCount", statements[1] as AggregateExpressionToken); }
public void ParseApplyWithMultipleTransformationShouldReturnTransformations() { string apply = "groupby((UnitPrice), aggregate(SalesPrice with average as RetailPrice))/filter(UnitPrice eq 5)/aggregate(CustomerId with sum as Total, SharePrice with countdistinct as SharePriceDistinctCount)"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(3); List <QueryToken> transformations = actual.ToList(); // verify groupby GroupByToken groupBy = transformations[0] as GroupByToken; groupBy.Should().NotBeNull(); VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy); groupBy.Properties.Should().HaveCount(1); groupBy.Child.Should().NotBeNull(); AggregateToken groupByAggregate = groupBy.Child as AggregateToken; groupByAggregate.AggregateExpressions.Should().HaveCount(1); VerifyAggregateExpressionToken("SalesPrice", AggregationMethodDefinition.Average, "RetailPrice", groupByAggregate.AggregateExpressions.First() as AggregateExpressionToken); // verify filter BinaryOperatorToken filter = transformations[1] as BinaryOperatorToken; VerifyBinaryOperatorToken <int>("UnitPrice", BinaryOperatorKind.Equal, 5, filter); // verify aggregate AggregateToken aggregate = transformations[2] as AggregateToken; aggregate.Should().NotBeNull(); aggregate.AggregateExpressions.Should().HaveCount(2); List <AggregateTokenBase> aggregateExpressions = aggregate.AggregateExpressions.ToList(); VerifyAggregateExpressionToken("CustomerId", AggregationMethodDefinition.Sum, "Total", aggregateExpressions[0] as AggregateExpressionToken); VerifyAggregateExpressionToken("SharePrice", AggregationMethodDefinition.CountDistinct, "SharePriceDistinctCount", aggregateExpressions[1] as AggregateExpressionToken); }
public void ParseApplyWithGroupByAndAggregateShouldReturnGroupByToken() { string apply = "groupby((UnitPrice), aggregate(SalesPrice with average as RetailPrice))"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(1); GroupByToken groupBy = actual.First() as GroupByToken; VerifyGroupByTokenProperties(new string[] { "UnitPrice" }, groupBy); groupBy.Child.Should().NotBeNull(); AggregateToken aggregate = groupBy.Child as AggregateToken; aggregate.AggregateExpressions.Should().HaveCount(1); VerifyAggregateExpressionToken("SalesPrice", AggregationMethodDefinition.Average, "RetailPrice", aggregate.AggregateExpressions.First() as AggregateExpressionToken); }
public void ParseApplyWithExpandFollowedByAggregateShouldParseSuccessfully() { string apply = "expand(Sales, filter(Amount gt 3))/aggregate($count as Count)"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); Assert.NotNull(actual); Assert.Equal(2, actual.Count()); ExpandToken expand = (ExpandToken)actual.First(); Assert.Single(expand.ExpandTerms); ExpandTermToken expandTerm = expand.ExpandTerms.First(); Assert.Equal(QueryTokenKind.ExpandTerm, expandTerm.Kind); Assert.Equal("Sales", expandTerm.PathToNavigationProp.Identifier); Assert.NotNull(expandTerm.FilterOption); AggregateToken aggregate = (AggregateToken)actual.Last(); Assert.Single(aggregate.AggregateExpressions); }
public void ParseApplyWithExpandFollowedByAggregateShouldParseSuccessfully() { string apply = "expand(Sales, filter(Amount gt 3))/aggregate($count as Count)"; IEnumerable <QueryToken> actual = this.testSubject.ParseApply(apply); actual.Should().NotBeNull(); actual.Should().HaveCount(2); ExpandToken expand = (ExpandToken)actual.First(); expand.ExpandTerms.Should().HaveCount(1); ExpandTermToken expandTerm = expand.ExpandTerms.First(); expandTerm.Kind.ShouldBeEquivalentTo(QueryTokenKind.ExpandTerm); expandTerm.PathToNavigationProp.Identifier.ShouldBeEquivalentTo("Sales"); expandTerm.FilterOption.Should().NotBeNull(); AggregateToken aggregate = (AggregateToken)actual.Last(); aggregate.AggregateExpressions.Should().HaveCount(1); }
public void StatementsSetCorrectly() { var token = new AggregateToken(statements); ((object)token.Expressions).Should().Be(statements); }
public bool Visit(AggregateToken tokenIn) { throw new NotSupportedException(string.Format(CultureInfo.CurrentCulture, "QueryToken of type '{0}' is not supported.", tokenIn.Kind)); }
public void StatementsSetCorrectly() { AggregateToken token = new AggregateToken(statements); Assert.Same(statements, token.AggregateExpressions); }
public void KindIsSetCorrectly() { var token = new AggregateToken(statements); token.Kind.Should().Be(QueryTokenKind.Aggregate); }
public void KindIsSetCorrectly() { AggregateToken token = new AggregateToken(statements); Assert.Equal(QueryTokenKind.Aggregate, token.Kind); }
public Expression Visit(AggregateToken tokenIn) { throw new NotImplementedException(); }
/// <summary> /// Visits an AggregateToken /// </summary> /// <param name="tokenIn">The AggregateToken to visit</param> /// <returns>A T bound to this AggregateToken</returns> public virtual T Visit(AggregateToken tokenIn) { throw new NotImplementedException(); }