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); }