public static RenderedProjectionDefinition <TResult> TranslateGroup <TKey, TDocument, TResult>(Expression <Func <TDocument, TKey> > idProjector, Expression <Func <IGrouping <TKey, TDocument>, TResult> > groupProjector, IBsonSerializer <TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry) { var keyBinder = new SerializationInfoBinder(serializerRegistry); var boundKeyExpression = BindSerializationInfo(keyBinder, idProjector, parameterSerializer); if (!(boundKeyExpression is ISerializationExpression)) { var keySerializer = SerializerBuilder.Build(boundKeyExpression, serializerRegistry); boundKeyExpression = new SerializationExpression( boundKeyExpression, new BsonSerializationInfo(null, keySerializer, typeof(TKey))); } var idExpression = new IdExpression(boundKeyExpression, ((ISerializationExpression)boundKeyExpression).SerializationInfo); var groupBinder = new GroupSerializationInfoBinder(BsonSerializer.SerializerRegistry); groupBinder.RegisterMemberReplacement(typeof(IGrouping <TKey, TDocument>).GetProperty("Key"), idExpression); var groupSerializer = new ArraySerializer <TDocument>(parameterSerializer); var boundGroupExpression = BindSerializationInfo(groupBinder, groupProjector, groupSerializer); var projectionSerializer = (IBsonSerializer <TResult>)SerializerBuilder.Build(boundGroupExpression, serializerRegistry); var projection = ProjectionBuilder.Build(boundGroupExpression).AsBsonDocument; // must have an "_id" in a group document if (!projection.Contains("_id")) { var idProjection = ProjectionBuilder.Build(boundKeyExpression); projection.InsertAt(0, new BsonElement("_id", idProjection)); } return(new RenderedProjectionDefinition <TResult>(projection, projectionSerializer)); }
private SerializationExpression BuildProjector(ProjectionExpression projection, ProjectionBindingContext context, GroupIdExpression id, Expression selector) { BsonSerializationInfo projectorSerializationInfo; var projectorSerializationExpression = projection.Projector as ISerializationExpression; if (projectorSerializationExpression != null) { projectorSerializationInfo = projectorSerializationExpression.SerializationInfo; } else { var projectorSerializer = context.SerializerRegistry.GetSerializer(projection.Projector.Type); projectorSerializationInfo = new BsonSerializationInfo( null, projectorSerializer, projectorSerializer.ValueType); } var serializerType = typeof(GroupingDeserializer <,>).MakeGenericType(id.Type, projection.Projector.Type); var serializer = (IBsonSerializer)Activator.CreateInstance(serializerType, id.SerializationInfo, projectorSerializationInfo); var info = new BsonSerializationInfo(null, serializer, serializer.ValueType); var projector = new SerializationExpression(selector, info); return(projector); }
private Expression BindSelector(ProjectionExpression projection, ProjectionBindingContext context, Expression id, Expression node) { var lambda = ExtensionExpressionVisitor.GetLambda(node); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); var serializer = SerializerBuilder.Build(projection.Projector, context.SerializerRegistry); var sequenceSerializer = (IBsonSerializer)Activator.CreateInstance( typeof(ArraySerializer <>).MakeGenericType(projection.Projector.Type), new object[] { serializer }); var sequenceInfo = new BsonSerializationInfo( null, sequenceSerializer, sequenceSerializer.ValueType); var sequenceExpression = new SerializationExpression( lambda.Parameters[1], sequenceInfo); binder.RegisterParameterReplacement(lambda.Parameters[0], id); binder.RegisterParameterReplacement(lambda.Parameters[1], sequenceExpression); var correlationId = Guid.NewGuid(); context.GroupMap.Add(sequenceExpression, correlationId); var bound = binder.Bind(lambda.Body); return(CorrelatedAccumulatorRemover.Remove(bound, correlationId)); }
public override Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments) { // OfType is two operations in one. First we create WhereExpression // for the test. Second, we want to issue a conversion projection // using the selector parameter of a ProjectionExpression such that // the conversion will be propogated to all future expressions. var newType = node.Method.GetGenericArguments()[0]; var parameter = Expression.Parameter(projection.Projector.Type); var predicate = Expression.Lambda( Expression.TypeIs(parameter, newType), parameter); var source = BindPredicate(projection, context, projection.Source, predicate); var serializer = context.SerializerRegistry.GetSerializer(newType); var info = new BsonSerializationInfo(null, serializer, newType); var projector = new SerializationExpression( Expression.Convert(projection.Projector, newType), info); return(new ProjectionExpression( source, projector)); }
public JasperBusRegistry() { UseFeature <ServiceBusFeature>(); _feature = Feature <ServiceBusFeature>(); Serialization = new SerializationExpression(this); }
public override Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments) { var aggregatorName = "SingleOrDefault"; var returnType = node.Method.ReturnType; if (node.Method.Name.EndsWith("Async")) { aggregatorName += "Async"; returnType = returnType.GetGenericArguments()[0]; // it's a task } var aggregator = CreateAggregator(aggregatorName, returnType); var source = projection.Source; var argument = arguments.FirstOrDefault(); if (argument != null && ExtensionExpressionVisitor.IsLambda(argument)) { source = BindPredicate(projection, context, source, argument); } var serializer = context.SerializerRegistry.GetSerializer(returnType); var accumulator = new AccumulatorExpression(returnType, AccumulatorType.Count, null); var serializationAccumulator = new SerializationExpression( accumulator, new BsonSerializationInfo("__agg0", serializer, serializer.ValueType)); var rootAccumulator = new RootAccumulatorExpression(source, serializationAccumulator); return(new ProjectionExpression( rootAccumulator, serializationAccumulator, aggregator)); }
private Expression BuildProjector(Expression selector, ProjectionBindingContext context) { var selectorNode = selector; if (!(selectorNode is ISerializationExpression)) { var serializer = SerializerBuilder.Build(selector, context.SerializerRegistry); BsonSerializationInfo info; switch (selector.NodeType) { case ExpressionType.MemberInit: case ExpressionType.New: info = new BsonSerializationInfo(null, serializer, serializer.ValueType); break; default: // this occurs when a computed field is used. This is a magic string // that shouldn't ever be reference anywhere else... info = new BsonSerializationInfo("__fld0", serializer, serializer.ValueType); break; } selectorNode = new SerializationExpression(selector, info); } return(selectorNode); }
// protected methods protected override Expression VisitBinary(BinaryExpression node) { var newNode = base.VisitBinary(node); var binary = newNode as BinaryExpression; if (binary != null && binary.NodeType == ExpressionType.ArrayIndex) { var serializationExpression = binary.Left as ISerializationExpression; if (serializationExpression != null) { var arraySerializer = serializationExpression.SerializationInfo.Serializer as IBsonArraySerializer; var indexExpression = binary.Right as ConstantExpression; if (arraySerializer != null && indexExpression != null && indexExpression.Type == typeof(int)) { var index = (int)indexExpression.Value; var itemSerializationInfo = arraySerializer.GetItemSerializationInfo(); itemSerializationInfo = new BsonSerializationInfo( index.ToString(), itemSerializationInfo.Serializer, itemSerializationInfo.NominalType); var serializationInfo = serializationExpression.SerializationInfo.Merge(itemSerializationInfo); newNode = new SerializationExpression(binary, serializationInfo); } } } return(newNode); }
protected internal override Expression VisitSerialization(SerializationExpression node) { if (node.SerializationInfo.ElementName != null) { _serializationExpressions.Add(node); } return(node); }
private BsonValue BuildSerialization(SerializationExpression node) { if (string.IsNullOrWhiteSpace(node.SerializationInfo.ElementName)) { return(BuildValue(node.Expression)); } return("$" + node.SerializationInfo.ElementName); }
private static Expression BindSerializationInfo(SerializationInfoBinder binder, LambdaExpression node, IBsonSerializer parameterSerializer) { var evaluatedBody = PartialEvaluator.Evaluate(node.Body); var parameterSerializationInfo = new BsonSerializationInfo(null, parameterSerializer, parameterSerializer.ValueType); var parameterExpression = new SerializationExpression(node.Parameters[0], parameterSerializationInfo); binder.RegisterParameterReplacement(node.Parameters[0], parameterExpression); return(binder.Bind(evaluatedBody)); }
protected internal override Expression VisitSerialization(SerializationExpression node) { if (node.SerializationInfo.Serializer.ValueType == _valueType) { _serializer = node.SerializationInfo.Serializer; return(node); } return(base.VisitSerialization(node)); }
protected override Expression VisitSerialization(SerializationExpression node) { if (node.SerializationInfo.ElementName != null && node.SerializationInfo.ElementName.StartsWith(_oldName)) { return(new SerializationExpression( node.Expression, node.SerializationInfo.WithNewName(GetReplacementName(node.SerializationInfo.ElementName)))); } return(base.VisitSerialization(node)); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments) { var collectionLambda = ExtensionExpressionVisitor.GetLambda(arguments.First()); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(collectionLambda.Parameters[0], projection.Projector); var collectionSelector = binder.Bind(collectionLambda.Body) as SerializationExpression; if (collectionSelector == null) { var message = string.Format("Unable to determine the collection selector in the tree: {0}", node.ToString()); throw new NotSupportedException(message); } var collectionArraySerializer = collectionSelector.SerializationInfo.Serializer as IBsonArraySerializer; BsonSerializationInfo collectionItemSerializationInfo; if (collectionArraySerializer == null || !collectionArraySerializer.TryGetItemSerializationInfo(out collectionItemSerializationInfo)) { var message = string.Format("The collection selector's serializer must implement IBsonArraySerializer: {0}", node.ToString()); throw new NotSupportedException(message); } Expression resultSelector; if (arguments.Count() == 2) { var resultLambda = ExtensionExpressionVisitor.GetLambda(arguments.Last()); binder.RegisterParameterReplacement(resultLambda.Parameters[0], projection.Projector); binder.RegisterParameterReplacement( resultLambda.Parameters[1], new SerializationExpression( resultLambda.Parameters[1], collectionItemSerializationInfo.WithNewName(collectionSelector.SerializationInfo.ElementName))); resultSelector = binder.Bind(resultLambda.Body); } else { resultSelector = new SerializationExpression( collectionSelector, collectionItemSerializationInfo.WithNewName(collectionSelector.SerializationInfo.ElementName)); } var projector = BuildProjector(resultSelector, context); return(new ProjectionExpression( new SelectManyExpression( projection.Source, collectionSelector, resultSelector), projector)); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments) { var distinct = new DistinctExpression(projection.Source, projection.Projector); var serializer = SerializerBuilder.Build(projection.Projector, context.SerializerRegistry); var info = new BsonSerializationInfo("_id", serializer, serializer.ValueType); var projector = new SerializationExpression(projection.Projector, info); return(new ProjectionExpression( distinct, projector)); }
private IBsonSerializer BuildProjectedSerializer(ProjectionMapping mapping) { // We are building a serializer specifically for a projected type based // on serialization information collected from other serializers. // We cannot cache this in the serializer registry because the compiler reuses // the same anonymous type definition in different contexts as long as they // are structurally equatable. As such, it might be that two different queries // projecting the same shape might need to be deserialized differently. var classMapType = typeof(BsonClassMap <>).MakeGenericType(mapping.Expression.Type); BsonClassMap classMap = (BsonClassMap)Activator.CreateInstance(classMapType); foreach (var memberMapping in mapping.Members) { var serializationExpression = memberMapping.Expression as ISerializationExpression; if (serializationExpression == null) { var serializer = Build(memberMapping.Expression); var serializationInfo = new BsonSerializationInfo( memberMapping.Member.Name, serializer, TypeHelper.GetMemberType(memberMapping.Member)); serializationExpression = new SerializationExpression( memberMapping.Expression, serializationInfo); } var memberMap = classMap.MapMember(memberMapping.Member) .SetSerializer(serializationExpression.SerializationInfo.Serializer) .SetElementName(memberMapping.Member.Name); if (classMap.IdMemberMap == null && serializationExpression is IdExpression) { classMap.SetIdMember(memberMap); } } var mappedParameters = mapping.Members .Where(x => x.Parameter != null) .OrderBy(x => x.Parameter.Position) .Select(x => x.Member) .ToList(); if (mappedParameters.Count > 0) { classMap.MapConstructor(mapping.Constructor) .SetArguments(mappedParameters); } var serializerType = typeof(BsonClassMapSerializer <>).MakeGenericType(mapping.Expression.Type); return((IBsonSerializer)Activator.CreateInstance(serializerType, classMap.Freeze())); }
private IBsonSerializer BuildSerializerForAnonymousType(NewExpression node) { // We are building a serializer specifically for an anonymous type based // on serialization information collected from other serializers. // We cannot cache this because the compiler reuses the same anonymous type // definition in different contexts as long as they are structurally equatable. // As such, it might be that two different queries projecting the same shape // might need to be deserialized differently. var classMapType = typeof(BsonClassMap <>).MakeGenericType(node.Type); BsonClassMap classMap = (BsonClassMap)Activator.CreateInstance(classMapType); var properties = node.Type.GetProperties(); var parameterToPropertyMap = from parameter in node.Constructor.GetParameters() join property in properties on parameter.Name equals property.Name select new { Parameter = parameter, Property = property }; foreach (var parameterToProperty in parameterToPropertyMap) { var argument = node.Arguments[parameterToProperty.Parameter.Position]; var serializationExpression = argument as ISerializationExpression; if (serializationExpression == null) { var serializer = Build(argument); var serializationInfo = new BsonSerializationInfo(parameterToProperty.Property.Name, serializer, parameterToProperty.Property.PropertyType); serializationExpression = new SerializationExpression( node.Arguments[parameterToProperty.Parameter.Position], serializationInfo); } var memberMap = classMap.MapMember(parameterToProperty.Property) .SetSerializer(serializationExpression.SerializationInfo.Serializer) .SetElementName(parameterToProperty.Property.Name); if (classMap.IdMemberMap == null && serializationExpression is IdExpression) { classMap.SetIdMember(memberMap); } //TODO: Need to set default value as well... } // Anonymous types are immutable and have all their values passed in via a ctor. classMap.MapConstructor(node.Constructor, properties.Select(x => x.Name).ToArray()); classMap.Freeze(); var serializerType = typeof(BsonClassMapSerializer <>).MakeGenericType(node.Type); return((IBsonSerializer)Activator.CreateInstance(serializerType, classMap)); }
protected override Expression VisitSerialization(SerializationExpression node) { if (!_fields.Any(x => x.SerializationInfo.ElementName == node.SerializationInfo.ElementName && x.SerializationInfo.NominalType.Equals(node.SerializationInfo.NominalType))) { return(Visit(node.Expression)); } return(Expression.Call( _replacementParameter, "GetValue", new[] { node.Type }, Expression.Constant(node.SerializationInfo.ElementName), Expression.Constant(TypeHelper.GetDefault(node.SerializationInfo.NominalType), typeof(object)))); }
/// <inheritdoc /> public override RenderedFieldDefinition Render(IBsonSerializer <TDocument> documentSerializer, IBsonSerializerRegistry serializerRegistry) { var binder = new SerializationInfoBinder(serializerRegistry); var parameterSerializationInfo = new BsonSerializationInfo(null, documentSerializer, documentSerializer.ValueType); var parameterExpression = new SerializationExpression(_expression.Parameters[0], parameterSerializationInfo); binder.RegisterParameterReplacement(_expression.Parameters[0], parameterExpression); var bound = binder.Bind(_expression.Body) as ISerializationExpression; if (bound == null) { var message = string.Format("Unable to determine the serialization information for {0}.", _expression); throw new InvalidOperationException(message); } return(new RenderedFieldDefinition(bound.SerializationInfo.ElementName, bound.SerializationInfo.Serializer)); }
public override Expression Bind(Expressions.ProjectionExpression projection, ProjectionBindingContext context, System.Linq.Expressions.MethodCallExpression node, IEnumerable <System.Linq.Expressions.Expression> arguments) { var aggregatorName = "Single"; var returnType = node.Method.ReturnType; if (node.Method.Name.EndsWith("Async")) { aggregatorName += "Async"; returnType = returnType.GetGenericArguments()[0]; } var aggregator = CreateAggregator(aggregatorName, returnType); var source = projection.Source; var argument = arguments.FirstOrDefault(); if (argument != null && ExtensionExpressionVisitor.IsLambda(argument)) { var lambda = ExtensionExpressionVisitor.GetLambda(argument); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); argument = binder.Bind(lambda.Body); } else { argument = projection.Projector; var select = source as SelectExpression; if (select != null) { source = select.Source; } } var serializer = context.SerializerRegistry.GetSerializer(returnType); var accumulator = new AccumulatorExpression(returnType, AccumulatorType, argument); var serializationAccumulator = new SerializationExpression( accumulator, new BsonSerializationInfo("__agg0", serializer, serializer.ValueType)); var rootAccumulator = new RootAccumulatorExpression(source, serializationAccumulator); return(new ProjectionExpression( rootAccumulator, serializationAccumulator, aggregator)); }
private GroupIdExpression BindId(ProjectionExpression projection, ProjectionBindingContext context, Expression node) { var lambda = ExtensionExpressionVisitor.GetLambda(node); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var selector = binder.Bind(lambda.Body); if (!(selector is ISerializationExpression)) { var serializer = SerializerBuilder.Build(selector, context.SerializerRegistry); selector = new SerializationExpression( selector, new BsonSerializationInfo(null, serializer, serializer.ValueType)); } return(new GroupIdExpression(selector, ((ISerializationExpression)selector).SerializationInfo)); }
private BsonClassMap BuildClassMap(Type type, ProjectionMapping mapping) { if (type == null || type == typeof(object)) { return(null); } var baseClassMap = BuildClassMap(type.BaseType, mapping); if (baseClassMap != null) { baseClassMap.Freeze(); } var classMap = new BsonClassMap(type, baseClassMap); foreach (var memberMapping in mapping.Members.Where(x => x.Member.DeclaringType == type)) { var serializationExpression = memberMapping.Expression as ISerializationExpression; if (serializationExpression == null) { var serializer = Build(memberMapping.Expression); var serializationInfo = new BsonSerializationInfo( memberMapping.Member.Name, serializer, GetMemberType(memberMapping.Member)); serializationExpression = new SerializationExpression( memberMapping.Expression, serializationInfo); } var memberMap = classMap.MapMember(memberMapping.Member) .SetSerializer(serializationExpression.SerializationInfo.Serializer) .SetElementName(memberMapping.Member.Name); if (classMap.IdMemberMap == null && serializationExpression is GroupIdExpression) { classMap.SetIdMember(memberMap); } } return(classMap); }
protected override Expression VisitSerialization(SerializationExpression node) { if (node.SerializationInfo.ElementName.StartsWith(_prefix)) { var name = node.SerializationInfo.ElementName; if (name == _prefix) { name = ""; } else { name = name.Remove(0, _prefix.Length + 1); } return(new SerializationExpression( node.Expression, node.SerializationInfo.WithNewName(name))); } return(base.VisitSerialization(node)); }
public static RenderedProjectionDefinition <TProjection> Translate <TDocument, TProjection>(Expression <Func <TDocument, TProjection> > projector, IBsonSerializer <TDocument> parameterSerializer) { var parameterSerializationInfo = new BsonSerializationInfo(null, parameterSerializer, parameterSerializer.ValueType); var parameterExpression = new SerializationExpression(projector.Parameters[0], parameterSerializationInfo); var binder = new SerializationInfoBinder(BsonSerializer.SerializerRegistry); binder.RegisterParameterReplacement(projector.Parameters[0], parameterExpression); var normalizedBody = Normalizer.Normalize(projector.Body); var evaluatedBody = PartialEvaluator.Evaluate(normalizedBody); var boundExpression = binder.Bind(evaluatedBody); var candidateFields = FieldGatherer.Gather(boundExpression); var fields = GetUniqueFieldsByHierarchy(candidateFields); var serializationInfo = fields.Select(x => x.SerializationInfo).ToList(); var replacementParameter = Expression.Parameter(typeof(ProjectedObject), "document"); var translator = new FindProjectionTranslator(projector.Parameters[0], replacementParameter, fields); var newProjector = Expression.Lambda <Func <ProjectedObject, TProjection> >( translator.Visit(boundExpression), replacementParameter); BsonDocument projectionDocument; IBsonSerializer <TProjection> serializer; if (translator._fullDocument) { projectionDocument = null; serializer = new ProjectingDeserializer <TDocument, TProjection>(parameterSerializer, projector.Compile()); } else { projectionDocument = GetProjectionDocument(serializationInfo); var projectedObjectSerializer = new ProjectedObjectDeserializer(serializationInfo); serializer = new ProjectingDeserializer <ProjectedObject, TProjection>(projectedObjectSerializer, newProjector.Compile()); } return(new RenderedProjectionDefinition <TProjection>(projectionDocument, serializer)); }
public static ProjectionInfo <TResult> TranslateGroup <TKey, TDocument, TResult>(Expression <Func <TDocument, TKey> > idProjector, Expression <Func <IGrouping <TKey, TDocument>, TResult> > groupProjector, IBsonSerializer <TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry) { if (groupProjector.Body.NodeType != ExpressionType.New) { throw new NotSupportedException("Must use an anonymous type for constructing $group pipeline operators."); } var keyBinder = new SerializationInfoBinder(serializerRegistry); var boundKeyExpression = BindSerializationInfo(keyBinder, idProjector, parameterSerializer); if (!(boundKeyExpression is ISerializationExpression)) { var keySerializer = SerializerBuilder.Build(boundKeyExpression, serializerRegistry); boundKeyExpression = new SerializationExpression( boundKeyExpression, new BsonSerializationInfo(null, keySerializer, typeof(TKey))); } var idExpression = new IdExpression(boundKeyExpression, ((ISerializationExpression)boundKeyExpression).SerializationInfo); var groupBinder = new GroupSerializationInfoBinder(BsonSerializer.SerializerRegistry); groupBinder.RegisterMemberReplacement(typeof(IGrouping <TKey, TDocument>).GetProperty("Key"), idExpression); var groupSerializer = new ArraySerializer <TDocument>(parameterSerializer); var boundGroupExpression = BindSerializationInfo(groupBinder, groupProjector, groupSerializer); var projectionSerializer = (IBsonSerializer <TResult>)SerializerBuilder.Build(boundGroupExpression, serializerRegistry); var projection = ProjectionBuilder.Build(boundGroupExpression).AsBsonDocument; // must have an "_id" in a group document if (!projection.Contains("_id")) { var idProjection = ProjectionBuilder.Build(boundKeyExpression); projection.InsertAt(0, new BsonElement("_id", idProjection)); } return(new ProjectionInfo <TResult>(projection, projectionSerializer)); }
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)); }
public override Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments) { LambdaExpression aggregator; if (node.Method.Name.EndsWith("Async")) { aggregator = CreateAsyncAggregator(); } else { aggregator = CreateSyncAggregator(); } var source = projection.Source; var argument = arguments.FirstOrDefault(); if (argument != null && ExtensionExpressionVisitor.IsLambda(argument)) { source = BindPredicate(projection, context, source, argument); } source = new TakeExpression(source, 1); var serializer = context.SerializerRegistry.GetSerializer(typeof(int)); var accumulator = new AccumulatorExpression(typeof(int), AccumulatorType.Count, null); var serializationAccumulator = new SerializationExpression( accumulator, new BsonSerializationInfo("__agg0", serializer, serializer.ValueType)); var rootAccumulator = new RootAccumulatorExpression(source, serializationAccumulator); return(new ProjectionExpression( rootAccumulator, serializationAccumulator, aggregator)); }
protected internal override Expression VisitSerialization(SerializationExpression node) { return(node); }