public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments) { var id = BindId(projection, context, arguments.Single()); var iGroupingType = typeof(IGrouping <,>).MakeGenericType(id.Type, projection.Projector.Type); var group = new CorrelatedGroupByExpression( Guid.NewGuid(), typeof(IEnumerable <>).MakeGenericType(iGroupingType), projection.Source, id, Enumerable.Empty <Expression>()); var groupingType = typeof(Grouping <,>).MakeGenericType(id.Type, projection.Projector.Type); Expression selector = Expression.Convert( Expression.New( groupingType.GetConstructors()[0], id), iGroupingType); var projector = BuildProjector(projection, context, id, selector); context.GroupMap.Add(projector, group.CorrelationId); return(new ProjectionExpression(group, projector)); }
private void VisitCorrelatedGroupBy(CorrelatedGroupByExpression node) { Visit(node.Source); var group = new BsonDocument(); group.Add("_id", AggregateLanguageTranslator.Translate(node.Id)); foreach (var accumulator in node.Accumulators) { var serializationExpression = (SerializationExpression)accumulator; group.Add( serializationExpression.SerializationInfo.ElementName, AggregateLanguageTranslator.Translate(serializationExpression.Expression)); } _stages.Add(new BsonDocument("$group", group)); }
protected internal override Expression VisitCorrelatedGroupBy(CorrelatedGroupByExpression node) { if (_lookup != null && _lookup.Contains(node.CorrelationId)) { var source = Visit(node.Source); var accumulators = new List <SerializationExpression>(); var comparer = new ExpressionComparer(); foreach (var correlatedAccumulator in _lookup[node.CorrelationId]) { var index = accumulators.FindIndex(x => comparer.Compare(x.Expression, correlatedAccumulator.Accumulator)); if (index == -1) { var serializer = _serializerRegistry.GetSerializer(correlatedAccumulator.Type); var info = new BsonSerializationInfo( "__agg" + accumulators.Count, serializer, serializer.ValueType); var serializationExpression = new SerializationExpression(correlatedAccumulator.Accumulator, info); accumulators.Add(serializationExpression); _map[correlatedAccumulator] = serializationExpression; } else { _map[correlatedAccumulator] = accumulators[index]; } } node = node.Update( source, node.Id, accumulators.OfType <Expression>()); } return(base.VisitCorrelatedGroupBy(node)); }