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 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); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { return new ProjectionExpression( new SkipExpression( projection.Source, (int)((ConstantExpression)arguments.Single()).Value), projection.Projector, projection.Aggregator); }
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); }
public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { var id = BindId(projection, context, arguments.First()); var selector = BindSelector(projection, context, id, arguments.Last()); var projector = BuildProjector(selector, context); return new ProjectionExpression( new GroupByWithResultSelectorExpression( projection.Source, selector), 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); }
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) { List<KeyValuePair<Registration, IMethodCallBinder>> namedBinders; if (!_binders.TryGetValue(node.Method.Name, out namedBinders)) { return null; } var binder = namedBinders.Where(x => x.Key.Filter(node)).Select(x => x.Value).FirstOrDefault(); if (binder == null) { return null; } return binder.Bind(projection, context, node, arguments); }
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(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments) { var aggregator = CreateAggregator(node.Method.Name, projection.Projector.Type); var source = projection.Source; var argument = arguments.FirstOrDefault(); if (argument != null && ExtensionExpressionVisitor.IsLambda(argument)) { source = BindPredicate(projection, context, source, argument); } source = new TakeExpression(source, 2); return new ProjectionExpression( source, projection.Projector, aggregator); }
protected internal override Expression VisitProjection(ProjectionExpression node) { var model = QueryableExecutionModelBuilder.Build(node, _serializerRegistry); Expression executor; if (_cancellationToken != null) { // we are async executor = Expression.Call( _provider, "ExecuteAsync", Type.EmptyTypes, Expression.Constant(model, typeof(QueryableExecutionModel)), _cancellationToken); if (node.Aggregator != null) { executor = Expression.Invoke( node.Aggregator, Expression.Convert(executor, node.Aggregator.Parameters[0].Type), _cancellationToken); } } else { // we are sync executor = Expression.Call( _provider, "Execute", Type.EmptyTypes, Expression.Constant(model, typeof(QueryableExecutionModel))); if (node.Aggregator != null) { executor = Expression.Invoke( node.Aggregator, Expression.Convert(executor, node.Aggregator.Parameters[0].Type)); } } return executor; }
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); }
private void VisitProjection(ProjectionExpression node) { Visit(node.Source); var serializationExpression = node.Projector as ISerializationExpression; if (serializationExpression != null) { var info = serializationExpression.SerializationInfo; if (info.ElementName != null) { // We are projecting a field, however the server only responds // with documents. So we'll create a projector that reads a document // and then projects the field out of it. var parameter = Expression.Parameter(typeof(ProjectedObject), "document"); var projector = Expression.Lambda( Expression.Call( parameter, "GetValue", new Type[] { info.Serializer.ValueType }, Expression.Constant(info.ElementName), Expression.Constant(info.Serializer.ValueType.GetDefaultValue(), typeof(object))), parameter); var innerSerializer = new ProjectedObjectDeserializer(new[] { info }); _serializer = (IBsonSerializer)Activator.CreateInstance( typeof(ProjectingDeserializer<,>).MakeGenericType(typeof(ProjectedObject), info.Serializer.ValueType), new object[] { innerSerializer, projector.Compile() }); return; } } _serializer = SerializerBuilder.Build(node.Projector, _serializerRegistry); }
protected internal override Expression VisitProjection(ProjectionExpression node) { _lookup = AccumulatorGatherer.Gather(node.Source).ToLookup(x => x.CorrelationId); return base.VisitProjection(node); }
public abstract Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments);
protected internal virtual Expression VisitProjection(ProjectionExpression node) { return node.Update( Visit(node.Source), Visit(node.Projector), VisitAndConvert<LambdaExpression>(node.Aggregator, "VisitPipeline")); }