Exemplo n.º 1
0
        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 IdExpression(boundKeyExpression, ((ISerializationExpression)boundKeyExpression).SerializationInfo);

            var groupBinder = new GroupSerializationInfoBinder(BsonSerializer.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           = ProjectionBuilder.Build(boundGroupExpression).AsBsonDocument;

            // must have an "_id" in a group document
            if (!projection.Contains("_id"))
            {
                var idProjection = ProjectionBuilder.Build(boundKeyExpression);
                projection.InsertAt(0, new BsonElement("_id", idProjection));
            }

            return(new RenderedProjectionDefinition <TResult>(projection, projectionSerializer));
        }
        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);
        }
Exemplo n.º 3
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));
        }
Exemplo n.º 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));
        }
Exemplo n.º 5
0
        public JasperBusRegistry()
        {
            UseFeature <ServiceBusFeature>();

            _feature      = Feature <ServiceBusFeature>();
            Serialization = new SerializationExpression(this);
        }
Exemplo n.º 6
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));
        }
        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);
        }
Exemplo n.º 8
0
        // protected methods
        protected override Expression VisitBinary(BinaryExpression node)
        {
            var newNode = base.VisitBinary(node);
            var binary  = newNode as BinaryExpression;

            if (binary != null && binary.NodeType == ExpressionType.ArrayIndex)
            {
                var serializationExpression = binary.Left as ISerializationExpression;
                if (serializationExpression != null)
                {
                    var arraySerializer = serializationExpression.SerializationInfo.Serializer as IBsonArraySerializer;
                    var indexExpression = binary.Right as ConstantExpression;
                    if (arraySerializer != null && indexExpression != null && indexExpression.Type == typeof(int))
                    {
                        var index = (int)indexExpression.Value;
                        var itemSerializationInfo = arraySerializer.GetItemSerializationInfo();
                        itemSerializationInfo = new BsonSerializationInfo(
                            index.ToString(),
                            itemSerializationInfo.Serializer,
                            itemSerializationInfo.NominalType);

                        var serializationInfo = serializationExpression.SerializationInfo.Merge(itemSerializationInfo);
                        newNode = new SerializationExpression(binary, serializationInfo);
                    }
                }
            }

            return(newNode);
        }
Exemplo n.º 9
0
 protected internal override Expression VisitSerialization(SerializationExpression node)
 {
     if (node.SerializationInfo.ElementName != null)
     {
         _serializationExpressions.Add(node);
     }
     return(node);
 }
Exemplo n.º 10
0
            private BsonValue BuildSerialization(SerializationExpression node)
            {
                if (string.IsNullOrWhiteSpace(node.SerializationInfo.ElementName))
                {
                    return(BuildValue(node.Expression));
                }

                return("$" + node.SerializationInfo.ElementName);
            }
        private static Expression BindSerializationInfo(SerializationInfoBinder binder, LambdaExpression node, IBsonSerializer parameterSerializer)
        {
            var evaluatedBody = PartialEvaluator.Evaluate(node.Body);
            var parameterSerializationInfo = new BsonSerializationInfo(null, parameterSerializer, parameterSerializer.ValueType);
            var parameterExpression        = new SerializationExpression(node.Parameters[0], parameterSerializationInfo);

            binder.RegisterParameterReplacement(node.Parameters[0], parameterExpression);
            return(binder.Bind(evaluatedBody));
        }
Exemplo n.º 12
0
            protected internal override Expression VisitSerialization(SerializationExpression node)
            {
                if (node.SerializationInfo.Serializer.ValueType == _valueType)
                {
                    _serializer = node.SerializationInfo.Serializer;
                    return(node);
                }

                return(base.VisitSerialization(node));
            }
Exemplo n.º 13
0
            protected 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));
            }
Exemplo n.º 14
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));
        }
Exemplo n.º 15
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));
        }
Exemplo n.º 16
0
            private IBsonSerializer BuildProjectedSerializer(ProjectionMapping mapping)
            {
                // We are building a serializer specifically for a projected type based
                // on serialization information collected from other serializers.
                // We cannot cache this in the serializer registry because the compiler reuses
                // the same anonymous type definition in different contexts as long as they
                // are structurally equatable. As such, it might be that two different queries
                // projecting the same shape might need to be deserialized differently.
                var          classMapType = typeof(BsonClassMap <>).MakeGenericType(mapping.Expression.Type);
                BsonClassMap classMap     = (BsonClassMap)Activator.CreateInstance(classMapType);

                foreach (var memberMapping in mapping.Members)
                {
                    var serializationExpression = memberMapping.Expression as ISerializationExpression;
                    if (serializationExpression == null)
                    {
                        var serializer        = Build(memberMapping.Expression);
                        var serializationInfo = new BsonSerializationInfo(
                            memberMapping.Member.Name,
                            serializer,
                            TypeHelper.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 IdExpression)
                    {
                        classMap.SetIdMember(memberMap);
                    }
                }

                var mappedParameters = mapping.Members
                                       .Where(x => x.Parameter != null)
                                       .OrderBy(x => x.Parameter.Position)
                                       .Select(x => x.Member)
                                       .ToList();

                if (mappedParameters.Count > 0)
                {
                    classMap.MapConstructor(mapping.Constructor)
                    .SetArguments(mappedParameters);
                }

                var serializerType = typeof(BsonClassMapSerializer <>).MakeGenericType(mapping.Expression.Type);

                return((IBsonSerializer)Activator.CreateInstance(serializerType, classMap.Freeze()));
            }
            private IBsonSerializer BuildSerializerForAnonymousType(NewExpression node)
            {
                // We are building a serializer specifically for an anonymous type based
                // on serialization information collected from other serializers.
                // We cannot cache this because the compiler reuses the same anonymous type
                // definition in different contexts as long as they are structurally equatable.
                // As such, it might be that two different queries projecting the same shape
                // might need to be deserialized differently.
                var          classMapType = typeof(BsonClassMap <>).MakeGenericType(node.Type);
                BsonClassMap classMap     = (BsonClassMap)Activator.CreateInstance(classMapType);

                var properties             = node.Type.GetProperties();
                var parameterToPropertyMap = from parameter in node.Constructor.GetParameters()
                                             join property in properties on parameter.Name equals property.Name
                                             select new { Parameter = parameter, Property = property };

                foreach (var parameterToProperty in parameterToPropertyMap)
                {
                    var argument = node.Arguments[parameterToProperty.Parameter.Position];
                    var serializationExpression = argument as ISerializationExpression;
                    if (serializationExpression == null)
                    {
                        var serializer        = Build(argument);
                        var serializationInfo = new BsonSerializationInfo(parameterToProperty.Property.Name, serializer, parameterToProperty.Property.PropertyType);
                        serializationExpression = new SerializationExpression(
                            node.Arguments[parameterToProperty.Parameter.Position],
                            serializationInfo);
                    }

                    var memberMap = classMap.MapMember(parameterToProperty.Property)
                                    .SetSerializer(serializationExpression.SerializationInfo.Serializer)
                                    .SetElementName(parameterToProperty.Property.Name);

                    if (classMap.IdMemberMap == null && serializationExpression is IdExpression)
                    {
                        classMap.SetIdMember(memberMap);
                    }

                    //TODO: Need to set default value as well...
                }

                // Anonymous types are immutable and have all their values passed in via a ctor.
                classMap.MapConstructor(node.Constructor, properties.Select(x => x.Name).ToArray());
                classMap.Freeze();

                var serializerType = typeof(BsonClassMapSerializer <>).MakeGenericType(node.Type);

                return((IBsonSerializer)Activator.CreateInstance(serializerType, classMap));
            }
Exemplo n.º 18
0
        protected override Expression VisitSerialization(SerializationExpression node)
        {
            if (!_fields.Any(x => x.SerializationInfo.ElementName == node.SerializationInfo.ElementName &&
                             x.SerializationInfo.NominalType.Equals(node.SerializationInfo.NominalType)))
            {
                return(Visit(node.Expression));
            }

            return(Expression.Call(
                       _replacementParameter,
                       "GetValue",
                       new[] { node.Type },
                       Expression.Constant(node.SerializationInfo.ElementName),
                       Expression.Constant(TypeHelper.GetDefault(node.SerializationInfo.NominalType), typeof(object))));
        }
Exemplo n.º 19
0
        /// <inheritdoc />
        public override RenderedFieldDefinition Render(IBsonSerializer <TDocument> documentSerializer, IBsonSerializerRegistry serializerRegistry)
        {
            var binder = new SerializationInfoBinder(serializerRegistry);
            var parameterSerializationInfo = new BsonSerializationInfo(null, documentSerializer, documentSerializer.ValueType);
            var parameterExpression        = new SerializationExpression(_expression.Parameters[0], parameterSerializationInfo);

            binder.RegisterParameterReplacement(_expression.Parameters[0], parameterExpression);
            var bound = binder.Bind(_expression.Body) as ISerializationExpression;

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

            return(new RenderedFieldDefinition(bound.SerializationInfo.ElementName, bound.SerializationInfo.Serializer));
        }
Exemplo n.º 20
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));
        }
        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));
        }
Exemplo n.º 22
0
        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 override Expression VisitSerialization(SerializationExpression node)
        {
            if (node.SerializationInfo.ElementName.StartsWith(_prefix))
            {
                var name = node.SerializationInfo.ElementName;
                if (name == _prefix)
                {
                    name = "";
                }
                else
                {
                    name = name.Remove(0, _prefix.Length + 1);
                }
                return(new SerializationExpression(
                           node.Expression,
                           node.SerializationInfo.WithNewName(name)));
            }

            return(base.VisitSerialization(node));
        }
Exemplo n.º 24
0
        public static RenderedProjectionDefinition <TProjection> Translate <TDocument, TProjection>(Expression <Func <TDocument, TProjection> > projector, IBsonSerializer <TDocument> parameterSerializer)
        {
            var parameterSerializationInfo = new BsonSerializationInfo(null, parameterSerializer, parameterSerializer.ValueType);
            var parameterExpression        = new SerializationExpression(projector.Parameters[0], parameterSerializationInfo);
            var binder = new SerializationInfoBinder(BsonSerializer.SerializerRegistry);

            binder.RegisterParameterReplacement(projector.Parameters[0], parameterExpression);
            var normalizedBody  = Normalizer.Normalize(projector.Body);
            var evaluatedBody   = PartialEvaluator.Evaluate(normalizedBody);
            var boundExpression = binder.Bind(evaluatedBody);
            var candidateFields = FieldGatherer.Gather(boundExpression);

            var fields = GetUniqueFieldsByHierarchy(candidateFields);

            var serializationInfo = fields.Select(x => x.SerializationInfo).ToList();

            var replacementParameter = Expression.Parameter(typeof(ProjectedObject), "document");

            var translator   = new FindProjectionTranslator(projector.Parameters[0], replacementParameter, fields);
            var newProjector = Expression.Lambda <Func <ProjectedObject, TProjection> >(
                translator.Visit(boundExpression),
                replacementParameter);

            BsonDocument projectionDocument;
            IBsonSerializer <TProjection> serializer;

            if (translator._fullDocument)
            {
                projectionDocument = null;
                serializer         = new ProjectingDeserializer <TDocument, TProjection>(parameterSerializer, projector.Compile());
            }
            else
            {
                projectionDocument = GetProjectionDocument(serializationInfo);
                var projectedObjectSerializer = new ProjectedObjectDeserializer(serializationInfo);
                serializer = new ProjectingDeserializer <ProjectedObject, TProjection>(projectedObjectSerializer, newProjector.Compile());
            }

            return(new RenderedProjectionDefinition <TProjection>(projectionDocument, serializer));
        }
        public static ProjectionInfo <TResult> TranslateGroup <TKey, TDocument, TResult>(Expression <Func <TDocument, TKey> > idProjector, Expression <Func <IGrouping <TKey, TDocument>, TResult> > groupProjector, IBsonSerializer <TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry)
        {
            if (groupProjector.Body.NodeType != ExpressionType.New)
            {
                throw new NotSupportedException("Must use an anonymous type for constructing $group pipeline operators.");
            }

            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 IdExpression(boundKeyExpression, ((ISerializationExpression)boundKeyExpression).SerializationInfo);

            var groupBinder = new GroupSerializationInfoBinder(BsonSerializer.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           = ProjectionBuilder.Build(boundGroupExpression).AsBsonDocument;

            // must have an "_id" in a group document
            if (!projection.Contains("_id"))
            {
                var idProjection = ProjectionBuilder.Build(boundKeyExpression);
                projection.InsertAt(0, new BsonElement("_id", idProjection));
            }

            return(new ProjectionInfo <TResult>(projection, projectionSerializer));
        }
Exemplo n.º 26
0
        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));
        }
Exemplo n.º 27
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));
        }
 protected internal override Expression VisitSerialization(SerializationExpression node)
 {
     return(node);
 }