コード例 #1
0
        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));
        }
コード例 #2
0
        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));
        }
コード例 #3
0
        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));
        }
コード例 #4
0
        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);
        }
コード例 #5
0
        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));
        }
コード例 #6
0
        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);
        }
        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);
        }
コード例 #8
0
        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;
        }
コード例 #9
0
 public Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments)
 {
     return(new ProjectionExpression(
                new TakeExpression(
                    projection.Source,
                    (int)((ConstantExpression)arguments.Single()).Value),
                projection.Projector,
                projection.Aggregator));
 }
コード例 #10
0
 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);
 }
コード例 #11
0
        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));
        }
コード例 #12
0
        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);
        }
コード例 #13
0
        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));
        }
コード例 #15
0
        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);
        }
コード例 #16
0
        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;
        }
コード例 #17
0
        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);
        }
コード例 #18
0
        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);
        }
コード例 #19
0
        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);
        }
コード例 #20
0
        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));
        }
コード例 #21
0
        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);
        }
コード例 #22
0
        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);
        }
コード例 #23
0
        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));
        }
コード例 #24
0
        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));
        }
コード例 #25
0
        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));
        }
コード例 #26
0
        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);
        }
コード例 #27
0
        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);
        }
コード例 #28
0
        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));
        }
コード例 #29
0
        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);
        }
コード例 #30
0
        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);
        }
コード例 #31
0
        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));
        }
コード例 #32
0
        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));
        }
コード例 #33
0
        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));
        }
コード例 #34
0
        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);
        }
コード例 #35
0
 public abstract Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable <Expression> arguments);
コード例 #36
0
        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);
        }
コード例 #37
0
 public abstract Expression Bind(ProjectionExpression projection, ProjectionBindingContext context, MethodCallExpression node, IEnumerable<Expression> arguments);