public static List <LambdaExpression> Execute(LambdaExpression expression) { // Find projection for aggregates calculated over sequence // specified by aggregatedSequence. // // Example: // x => new { // CountActive = x.Count(i => i.Active), // SumActive = x.Sum(i => i.Active ? i.Value : 0), // }; // // The following expressions are returned: // // i => i.Active // i => i.Acitve ? i.Value : 0 var finder = new AggregateProjectionFinder(); finder.aggregatedSequence = expression.Parameters.Count == 2 ? expression.Parameters[1] // Result selector parameter in GroupBy : expression.Parameters[0]; // Selector parameter in Select after GroupBy finder.Visit(expression); return(finder.result); }
private MethodCallExpression VisitGroupBy(MethodCallExpression groupByCall, LambdaExpression selectProjection) { var groupBy = QueryParser.ParseGroupBy(groupByCall); var projection = groupBy.ResultSelector ?? selectProjection; if (projection != null) { var referenceFieldAccessors = AggregateProjectionFinder.Execute(projection) .Select(ReferenceFieldAccessExtractor.Execute) .Where(item => item != null) .ToList(); if (referenceFieldAccessors.Count > 0) { groupBy.Source = Visit(groupBy.Source); if (groupBy.ElementSelector != null) { AddGroupByItemWrapper(groupBy, referenceFieldAccessors); } groupBy.Source = referenceFieldAccessors.Aggregate(groupBy.Source, AddProjectionPrefetch); return(QueryFactory.GroupBy(groupBy)); } } return(groupByCall); }