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 GroupIdExpression(boundKeyExpression, ((ISerializationExpression)boundKeyExpression).SerializationInfo); var groupBinder = new AccumulatorBinder(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 = AggregateLanguageTranslator.Translate(boundGroupExpression).AsBsonDocument; // must have an "_id" in a group document if (!projection.Contains("_id")) { var idProjection = AggregateLanguageTranslator.Translate(boundKeyExpression); projection.InsertAt(0, new BsonElement("_id", idProjection)); } return(new RenderedProjectionDefinition <TResult>(projection, projectionSerializer)); }
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 static Expression Bind(Expression node, IBsonSerializer rootSerializer, IBsonSerializerRegistry serializerRegistry) { var bindingContext = new PipelineBindingContext(serializerRegistry); var binder = new PipelineBinder(bindingContext, rootSerializer); node = binder.Bind(node); node = AccumulatorBinder.Bind(node, bindingContext); node = CorrelatedGroupRewriter.Rewrite(node); return(node); }
public static Expression Bind(Expression node, IBindingContext parent) { var bindingContext = new EmbeddedPipelineBindingContext(parent); var binder = new EmbeddedPipelineBinder(bindingContext); var bound = binder.Bind(node); bound = AccumulatorBinder.Bind(bound, bindingContext); return(CorrelatedGroupRewriter.Rewrite(bound)); }
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)); }
protected static Expression BindPredicate(ProjectionExpression projection, ProjectionBindingContext context, Expression source, Expression argument) { // this is actually a predicate that needs to be rendered as a WhereExpression var lambda = ExtensionExpressionVisitor.GetLambda(argument); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var predicate = binder.Bind(lambda.Body); source = new WhereExpression( source, predicate); return source; }
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); }
protected static Expression BindPredicate(ProjectionExpression projection, ProjectionBindingContext context, Expression source, Expression argument) { // this is actually a predicate that needs to be rendered as a WhereExpression var lambda = ExtensionExpressionVisitor.GetLambda(argument); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var predicate = binder.Bind(lambda.Body); source = new WhereExpression( source, predicate); return(source); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single()); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var predicate = binder.Bind(lambda.Body); return new ProjectionExpression( new WhereExpression( projection.Source, predicate), projection.Projector, projection.Aggregator); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments) { var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single()); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var predicate = binder.Bind(lambda.Body); return(new ProjectionExpression( new WhereExpression( projection.Source, predicate), projection.Projector, projection.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); }
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)); }
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); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { var source = projection.Source; var sortClauses = GatherPreviousSortClauses(projection.Source, out source); var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single()); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var direction = GetDirection(node.Method.Name); var ordering = binder.Bind(lambda.Body); sortClauses.Add(new SortClause(ordering, direction)); return new ProjectionExpression( new OrderByExpression( source, sortClauses), projection.Projector, projection.Aggregator); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single()); if (lambda.Body == lambda.Parameters[0]) { // we can ignore identity projections return projection; } var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var selector = binder.Bind(lambda.Body); var projector = BuildProjector(selector, context); return new ProjectionExpression( new SelectExpression( projection.Source, selector), projector); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments) { var source = projection.Source; var sortClauses = GatherPreviousSortClauses(projection.Source, out source); var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single()); var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var direction = GetDirection(node.Method.Name); var ordering = binder.Bind(lambda.Body); sortClauses.Add(new SortClause(ordering, direction)); return(new ProjectionExpression( new OrderByExpression( source, sortClauses), projection.Projector, projection.Aggregator)); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments) { var lambda = ExtensionExpressionVisitor.GetLambda(arguments.Single()); if (lambda.Body == lambda.Parameters[0]) { // we can ignore identity projections return(projection); } var binder = new AccumulatorBinder(context.GroupMap, context.SerializerRegistry); binder.RegisterParameterReplacement(lambda.Parameters[0], projection.Projector); var selector = binder.Bind(lambda.Body); var projector = BuildProjector(selector, context); return(new ProjectionExpression( new SelectExpression( projection.Source, selector), 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); }