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

            var groupBinder = new AccumulatorBinder(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           = AggregateLanguageTranslator.Translate(boundGroupExpression).AsBsonDocument;

            // must have an "_id" in a group document
            if (!projection.Contains("_id"))
            {
                var idProjection = AggregateLanguageTranslator.Translate(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);
        }