internal override RenderedFieldDefinition <TField> TranslateExpressionToField <TDocument, TField>(
            Expression <Func <TDocument, TField> > expression,
            IBsonSerializer <TDocument> documentSerializer,
            IBsonSerializerRegistry serializerRegistry,
            bool allowScalarValueForArrayField)
        {
            var lambda              = (LambdaExpression)PartialEvaluator.Evaluate(expression);
            var bindingContext      = new PipelineBindingContext(serializerRegistry);
            var parameterExpression = new DocumentExpression(documentSerializer);

            bindingContext.AddExpressionMapping(lambda.Parameters[0], parameterExpression);
            var bound = bindingContext.Bind(lambda.Body);

            bound = FieldExpressionFlattener.FlattenFields(bound);
            IFieldExpression field;

            if (!ExpressionHelper.TryGetExpression(bound, out field))
            {
                var message = string.Format("Unable to determine the serialization information for {0}.", expression);
                throw new InvalidOperationException(message);
            }

            var underlyingSerializer = field.Serializer;
            var fieldSerializer      = underlyingSerializer as IBsonSerializer <TField>;
            var valueSerializer      = (IBsonSerializer <TField>)FieldValueSerializerHelper.GetSerializerForValueType(underlyingSerializer, serializerRegistry, typeof(TField), allowScalarValueForArrayField);

            return(new RenderedFieldDefinition <TField>(field.FieldName, fieldSerializer, valueSerializer, underlyingSerializer));
        }
Beispiel #2
0
        private static Expression BindResult<TSource,TResult>(
            PipelineBindingContext bindingContext,
            Expression<Func<TSource, TResult>> expression,
            IBsonSerializer<TSource> sourceSerializer)
        {
            var parameterExpression = new DocumentExpression(sourceSerializer);
            bindingContext.AddExpressionMapping(expression.Parameters[0], parameterExpression);
            var node = PartialEvaluator.Evaluate(expression.Body);
            node = Transformer.Transform(node);
            node = bindingContext.Bind(node);

            var resultSerializer = bindingContext.GetSerializer(node.Type, node);
            return new AggregateExpressionExpression(node, resultSerializer);
        }
        private static Expression BindKeySelector <TKey, TDocument>(PipelineBindingContext bindingContext, Expression <Func <TDocument, TKey> > keySelector, IBsonSerializer <TDocument> parameterSerializer)
        {
            var parameterExpression = new DocumentExpression(parameterSerializer);

            bindingContext.AddExpressionMapping(keySelector.Parameters[0], parameterExpression);
            var node = PartialEvaluator.Evaluate(keySelector.Body);

            node = Transformer.Transform(node);
            node = bindingContext.Bind(node);

            var keySerializer = bindingContext.GetSerializer(node.Type, node);

            return(new GroupingKeyExpression(node, keySerializer));
        }
        public static RenderedProjectionDefinition <TProjection> Translate <TDocument, TProjection>(Expression <Func <TDocument, TProjection> > projector, IBsonSerializer <TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry)
        {
            var bindingContext     = new PipelineBindingContext(serializerRegistry);
            var documentExpression = new DocumentExpression(parameterSerializer);

            bindingContext.AddExpressionMapping(projector.Parameters[0], documentExpression);

            var node = PartialEvaluator.Evaluate(projector.Body);

            node = Transformer.Transform(node);
            node = bindingContext.Bind(node, isClientSideProjection: true);
            node = FieldExpressionFlattener.FlattenFields(node);

            BsonDocument projectionDocument = null;
            IBsonSerializer <TProjection> serializer;

            if (node is DocumentExpression)
            {
                serializer = new ProjectingDeserializer <TDocument, TProjection>(parameterSerializer, projector.Compile());
            }
            else
            {
                var candidateFields   = SerializationExpressionGatherer.Gather(node);
                var fields            = GetUniqueFieldsByHierarchy(candidateFields);
                var serializationInfo = fields.Select(x => new BsonSerializationInfo(x.FieldName, x.Serializer, x.Serializer.ValueType)).ToList();

                var projectedObjectExpression = Expression.Parameter(typeof(ProjectedObject), "document");
                var translator = new FindProjectionTranslator(documentExpression, projectedObjectExpression, fields);
                var translated = translator.Visit(node);
                if (translator._fullDocument)
                {
                    serializer = new ProjectingDeserializer <TDocument, TProjection>(parameterSerializer, projector.Compile());
                }
                else
                {
                    var newProjector = Expression.Lambda <Func <ProjectedObject, TProjection> >(
                        translated,
                        projectedObjectExpression);

                    projectionDocument = GetProjectionDocument(serializationInfo);
                    var projectedObjectSerializer = new ProjectedObjectDeserializer(serializationInfo);
                    serializer = new ProjectingDeserializer <ProjectedObject, TProjection>(projectedObjectSerializer, newProjector.Compile());
                }
            }

            return(new RenderedProjectionDefinition <TProjection>(projectionDocument, serializer));
        }
        public static RenderedProjectionDefinition <TResult> Translate <TDocument, TResult>(Expression <Func <TDocument, TResult> > projector, IBsonSerializer <TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry)
        {
            var bindingContext      = new PipelineBindingContext(serializerRegistry);
            var parameterExpression = new DocumentExpression(parameterSerializer);

            bindingContext.AddExpressionMapping(projector.Parameters[0], parameterExpression);

            var node = PartialEvaluator.Evaluate(projector.Body);

            node = Transformer.Transform(node);
            node = bindingContext.Bind(node);

            var projectionSerializer = bindingContext.GetSerializer(node.Type, node);
            var projection           = TranslateProject(node);

            return(new RenderedProjectionDefinition <TResult>(projection, (IBsonSerializer <TResult>)projectionSerializer));
        }
        private static Expression BindGroup <TKey, TDocument, TResult>(PipelineBindingContext bindingContext, Expression <Func <IGrouping <TKey, TDocument>, TResult> > groupProjector, IBsonSerializer <TDocument> parameterSerializer, Expression keySelector)
        {
            var groupSerializer = new ArraySerializer <TDocument>(parameterSerializer);
            var groupExpression = new DocumentExpression(groupSerializer);

            var correlationId = Guid.NewGuid();

            bindingContext.AddCorrelatingId(groupExpression, correlationId);
            bindingContext.AddExpressionMapping(groupProjector.Parameters[0], groupExpression);
            bindingContext.AddMemberMapping(typeof(IGrouping <TKey, TDocument>).GetProperty("Key"), keySelector);

            var node = PartialEvaluator.Evaluate(groupProjector.Body);

            node = Transformer.Transform(node);
            node = bindingContext.Bind(node);

            return(CorrelatedAccumulatorRemover.Remove(node, correlationId));
        }
Beispiel #7
0
        /// <inheritdoc />
        public override RenderedFieldDefinition Render(IBsonSerializer <TDocument> documentSerializer, IBsonSerializerRegistry serializerRegistry)
        {
            var bindingContext      = new PipelineBindingContext(serializerRegistry);
            var lambda              = ExpressionHelper.GetLambda(PartialEvaluator.Evaluate(_expression));
            var parameterExpression = new DocumentExpression(documentSerializer);

            bindingContext.AddExpressionMapping(lambda.Parameters[0], parameterExpression);
            var bound = bindingContext.Bind(lambda.Body);
            IFieldExpression field;

            if (!ExpressionHelper.TryGetExpression(bound, out field))
            {
                var message = string.Format("Unable to determine the serialization information for {0}.", _expression);
                throw new InvalidOperationException(message);
            }

            return(new RenderedFieldDefinition(field.FieldName, field.Serializer));
        }