예제 #1
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;
        }
예제 #2
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);
        }
        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
 protected override Expression VisitSerialization(SerializationExpression node)
 {
     if (node.SerializationInfo.ElementName != null)
     {
         _serializationExpressions.Add(node);
     }
     return(node);
 }
        public PipelineExpression(Expression source, SerializationExpression projector, ResultOperator resultOperator)
        {
            _source = Ensure.IsNotNull(source, nameof(source));
            _projector = Ensure.IsNotNull(projector, nameof(projector));
            _resultOperator = resultOperator;

            _type = _resultOperator == null ?
                typeof(IEnumerable<>).MakeGenericType(_projector.Type) :
                _resultOperator.Type;
        }
        public PipelineExpression Update(Expression source, SerializationExpression projector, ResultOperator resultOperator)
        {
            if (source != _source ||
                projector != _projector ||
                resultOperator != _resultOperator)
            {
                return new PipelineExpression(source, projector, resultOperator);
            }

            return this;
        }
예제 #7
0
        public PipelineExpression Update(Expression source, SerializationExpression projector, ResultOperator resultOperator)
        {
            if (source != _source ||
                projector != _projector ||
                resultOperator != _resultOperator)
            {
                return(new PipelineExpression(source, projector, resultOperator));
            }

            return(this);
        }
        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 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);
        }
예제 #10
0
        public PipelineExpression(Expression source, SerializationExpression projector, ResultOperator resultOperator)
        {
            _source = Ensure.IsNotNull(source, nameof(source));
            _projector = Ensure.IsNotNull(projector, nameof(projector));
            _resultOperator = resultOperator;

            if (_resultOperator == null)
            {
                _serializer = SerializerHelper.CreateEnumerableSerializer(_projector.Serializer);
                _type = typeof(IEnumerable<>).MakeGenericType(_projector.Type);
            }
            else
            {
                _serializer = _resultOperator.Serializer;
                _type = _resultOperator.Type;
            }
        }
예제 #11
0
        public PipelineExpression(Expression source, SerializationExpression projector, ResultOperator resultOperator)
        {
            _source         = Ensure.IsNotNull(source, nameof(source));
            _projector      = Ensure.IsNotNull(projector, nameof(projector));
            _resultOperator = resultOperator;

            if (_resultOperator == null)
            {
                _serializer = SerializerHelper.CreateEnumerableSerializer(_projector.Serializer);
                _type       = typeof(IEnumerable <>).MakeGenericType(_projector.Type);
            }
            else
            {
                _serializer = _resultOperator.Serializer;
                _type       = _resultOperator.Type;
            }
        }
        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);
        }
        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);
        }
        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);
        }
            protected internal 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);
            }
예제 #17
0
 public PipelineExpression(Expression source, SerializationExpression projector)
     : this(source, projector, null)
 {
 }
            protected internal override Expression VisitSerialization(SerializationExpression node)
            {
                if (node.SerializationInfo.Serializer.ValueType == _valueType)
                {
                    _serializer = node.SerializationInfo.Serializer;
                    return node;
                }

                return base.VisitSerialization(node);
            }
        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 internal virtual Expression VisitSerialization(SerializationExpression node)
 {
     return(node.Update(Visit(node.Expression)));
 }
 protected virtual Expression VisitSerialization(SerializationExpression node)
 {
     return(node);
 }
예제 #22
0
 public PipelineExpression(Expression source, SerializationExpression projector)
     : this(source, projector, null)
 {
 }
예제 #23
0
 private bool CompareSerialization(SerializationExpression a, SerializationExpression b)
 {
     return(Compare(a.Expression, b.Expression));
 }
 protected internal virtual Expression VisitSerialization(SerializationExpression node)
 {
     return node.Update(Visit(node.Expression));
 }
        private BsonValue BuildSerialization(SerializationExpression node)
        {
            if (string.IsNullOrWhiteSpace(node.SerializationInfo.ElementName))
            {
                return BuildValue(node.Expression);
            }

            return "$" + node.SerializationInfo.ElementName;
        }