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)); }
public static BsonValue Translate<TSource, TResult>( Expression<Func<TSource, TResult>> expression, IBsonSerializer<TSource> sourceSerializer, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions) { var bindingContext = new PipelineBindingContext(serializerRegistry); var boundExpression = BindResult(bindingContext, expression, sourceSerializer); return AggregateLanguageTranslator.Translate(boundExpression, translationOptions); }
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)); }
/// <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)); }
public static RenderedProjectionDefinition <TResult> Translate <TKey, TDocument, TResult>(Expression <Func <TDocument, TKey> > idProjector, Expression <Func <IGrouping <TKey, TDocument>, TResult> > groupProjector, IBsonSerializer <TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry) { var bindingContext = new PipelineBindingContext(serializerRegistry); var keySelector = BindKeySelector(bindingContext, idProjector, parameterSerializer); var boundGroupExpression = BindGroup(bindingContext, groupProjector, parameterSerializer, keySelector); var projectionSerializer = bindingContext.GetSerializer(boundGroupExpression.Type, boundGroupExpression); var projection = AggregateLanguageTranslator.Translate(boundGroupExpression).AsBsonDocument; // must have an "_id" in a group document if (!projection.Contains("_id")) { var idProjection = AggregateLanguageTranslator.Translate(keySelector); projection.InsertAt(0, new BsonElement("_id", idProjection)); } return(new RenderedProjectionDefinition <TResult>(projection, (IBsonSerializer <TResult>)projectionSerializer)); }