public static BsonDocument TranslateProject(Expression expression, ExpressionTranslationOptions translationOptions)
        {
            var projection = (BsonDocument)AggregateLanguageTranslator.Translate(expression, translationOptions);

            if (!projection.Contains("_id"))
            {
                projection.Add("_id", 0);
            }

            return(projection);
        }
        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));
        }
        internal override BsonValue TranslateExpressionToAggregateExpression <TSource, TResult>(
            Expression <Func <TSource, TResult> > expression,
            IBsonSerializer <TSource> sourceSerializer,
            IBsonSerializerRegistry serializerRegistry,
            ExpressionTranslationOptions translationOptions)
        {
            expression = (Expression <Func <TSource, TResult> >)PartialEvaluator.EvaluatePartially(expression);
            var context       = TranslationContext.Create(expression, sourceSerializer);
            var translation   = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, expression, sourceSerializer, asRoot: true);
            var simplifiedAst = AstSimplifier.Simplify(translation.Ast);

            return(simplifiedAst.Render());
        }
 internal override BsonValue TranslateExpressionToAggregateExpression <TSource, TResult>(
     Expression <Func <TSource, TResult> > expression,
     IBsonSerializer <TSource> sourceSerializer,
     IBsonSerializerRegistry serializerRegistry,
     ExpressionTranslationOptions translationOptions,
     TranslationContextData contextData = null)
 {
     if (contextData != null)
     {
         throw new InvalidOperationException("The LINQ2 provider does not support context data.");
     }
     return(AggregateExpressionTranslator.Translate(expression, sourceSerializer, serializerRegistry, translationOptions));
 }
        internal override RenderedProjectionDefinition <TOutput> TranslateExpressionToBucketOutputProjection <TInput, TValue, TOutput>(
            Expression <Func <TInput, TValue> > valueExpression,
            Expression <Func <IGrouping <TValue, TInput>, TOutput> > outputExpression,
            IBsonSerializer <TInput> documentSerializer,
            IBsonSerializerRegistry serializerRegistry,
            ExpressionTranslationOptions translationOptions)
        {
            var renderedOutput = AggregateGroupTranslator.Translate <TValue, TInput, TOutput>(valueExpression, outputExpression, documentSerializer, serializerRegistry, translationOptions);
            var document       = renderedOutput.Document;

            document.Remove("_id");
            return(new RenderedProjectionDefinition <TOutput>(document, renderedOutput.ProjectionSerializer));
        }
示例#6
0
        public void TranslateExpressionToAggregateExpression_should_return_expected_result()
        {
            var subject = LinqProviderAdapter.V3;
            Expression <Func <C, int> > expression = c => c.X;
            var serializerRegistry = BsonSerializer.SerializerRegistry;
            var sourceSerializer   = serializerRegistry.GetSerializer <C>();
            var translationOptions = new ExpressionTranslationOptions();

            var result = subject.TranslateExpressionToAggregateExpression(expression, sourceSerializer, serializerRegistry, translationOptions);

            var expectedResult = LinqProviderAdapter.V2.TranslateExpressionToAggregateExpression(expression, sourceSerializer, serializerRegistry, translationOptions);

            expectedResult.Should().Be("'$X'");
            result.Should().Be(expectedResult);
        }
示例#7
0
        public void TranslateExpressionToGroupProjection_should_throw()
        {
            WithAnonymousOutputType(g => new { count = g.Count() });

            void WithAnonymousOutputType <TOutput>(Expression <Func <IGrouping <int, C>, TOutput> > groupExpression)
            {
                var subject = LinqProviderAdapter.V3;
                Expression <Func <C, int> > idExpression = c => c.X;
                var serializerRegistry = BsonSerializer.SerializerRegistry;
                var documentSerializer = serializerRegistry.GetSerializer <C>();
                var translationOptions = new ExpressionTranslationOptions();

                var exception = Record.Exception(() => subject.TranslateExpressionToGroupProjection(idExpression, groupExpression, documentSerializer, serializerRegistry, translationOptions));

                exception.Should().BeOfType <InvalidOperationException>();
            }
        }
        public static QueryableTranslation Translate(Expression node, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
        {
            var translator = new QueryableTranslator(serializerRegistry, translationOptions);
            translator.Translate(node);

            var outputType = translator._outputSerializer.ValueType;
            var modelType = typeof(AggregateQueryableExecutionModel<>).MakeGenericType(outputType);
            var modelTypeInfo = modelType.GetTypeInfo();
            var outputSerializerInterfaceType = typeof(IBsonSerializer<>).MakeGenericType(new[] { outputType });
            var constructorParameterTypes = new Type[] { typeof(IEnumerable<BsonDocument>), outputSerializerInterfaceType };
            var constructorInfo = modelTypeInfo.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)
                .Where(c => c.GetParameters().Select(p => p.ParameterType).SequenceEqual(constructorParameterTypes))
                .Single();
            var constructorParameters = new object[] { translator._stages, translator._outputSerializer };
            var model = (QueryableExecutionModel)constructorInfo.Invoke(constructorParameters);

            return new QueryableTranslation(model, translator._resultTransformer);
        }
示例#9
0
        public void TranslateExpressionToBucketOutputProjection_should_return_expected_result()
        {
            var subject = LinqProviderAdapter.V3;
            Expression <Func <C, int> > valueExpression = c => c.X;
            Expression <Func <IGrouping <int, C>, int> > outputExpression = g => g.Count();
            var serializerRegistry = BsonSerializer.SerializerRegistry;
            var documentSerializer = serializerRegistry.GetSerializer <C>();
            var translationOptions = new ExpressionTranslationOptions();

            var result = subject.TranslateExpressionToBucketOutputProjection(valueExpression, outputExpression, documentSerializer, serializerRegistry, translationOptions);

            var expectedResult = LinqProviderAdapter.V2.TranslateExpressionToBucketOutputProjection(valueExpression, outputExpression, documentSerializer, serializerRegistry, translationOptions);

            expectedResult.Document.Should().Be("{ $sum : 1 }");
            expectedResult.ProjectionSerializer.Should().BeOfType <Int32Serializer>();
            result.Document.Should().Be(expectedResult.Document);
            result.ProjectionSerializer.Should().BeOfType(expectedResult.ProjectionSerializer.GetType());
        }
示例#10
0
        public void TranslateExpressionToProjection_should_return_expected_result()
        {
            WithAnonymousOutputType(c => new { id = c.Id, x = c.X });

            void WithAnonymousOutputType <TOutput>(Expression <Func <C, TOutput> > expression)
            {
                var subject            = LinqProviderAdapter.V3;
                var serializerRegistry = BsonSerializer.SerializerRegistry;
                var inputSerializer    = serializerRegistry.GetSerializer <C>();
                var translationOptions = new ExpressionTranslationOptions();

                var result = subject.TranslateExpressionToProjection(expression, inputSerializer, serializerRegistry, translationOptions);

                var expectedResult = LinqProviderAdapter.V2.TranslateExpressionToProjection(expression, inputSerializer, serializerRegistry, translationOptions);

                expectedResult.Document.Should().Be("{ id : '$_id', x : '$X', _id : 0 }");
                expectedResult.ProjectionSerializer.ValueType.Should().Be(typeof(TOutput));
                result.Document.Should().Be(expectedResult.Document);
                result.ProjectionSerializer.ValueType.Should().Be(expectedResult.ProjectionSerializer.ValueType);
            }
        }
示例#11
0
        private ProjectedResult <TResult> Group <TKey, TResult>(Expression <Func <Root, TKey> > idProjector, Expression <Func <IGrouping <TKey, Root>, TResult> > groupProjector, ExpressionTranslationOptions translationOptions)
        {
            var serializer     = BsonSerializer.SerializerRegistry.GetSerializer <Root>();
            var projectionInfo = AggregateGroupTranslator.Translate <TKey, Root, TResult>(idProjector, groupProjector, serializer, BsonSerializer.SerializerRegistry, translationOptions);

            var group = new BsonDocument("$group", projectionInfo.Document);
            var sort  = new BsonDocument("$sort", new BsonDocument("_id", 1));
            var list  = __collection.Aggregate <TResult>(new BsonDocumentStagePipelineDefinition <Root, TResult>(new[] { group, sort }, projectionInfo.ProjectionSerializer)).ToList();

            return(new ProjectedResult <TResult>
            {
                Projection = projectionInfo.Document,
                Value = (TResult)list[0]
            });
        }
        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, ExpressionTranslationOptions translationOptions)
        {
            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, translationOptions).AsBsonDocument;

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

            return(new RenderedProjectionDefinition <TResult>(projection, (IBsonSerializer <TResult>)projectionSerializer));
        }
示例#13
0
 private AggregateLanguageTranslator(ExpressionTranslationOptions translationOptions)
 {
     translationOptions     = translationOptions ?? ExpressionTranslationOptions.Default;
     _stringTranslationMode = translationOptions.StringTranslationMode.GetValueOrDefault(AggregateStringTranslationMode.Bytes);
 }
示例#14
0
        public static BsonValue Translate(Expression node, ExpressionTranslationOptions translationOptions)
        {
            var builder = new AggregateLanguageTranslator(translationOptions);

            return(builder.TranslateValue(node));
        }
 public QueryableTranslator(IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
 {
     _serializerRegistry = Ensure.IsNotNull(serializerRegistry, nameof(serializerRegistry));
     _translationOptions = translationOptions; // can be null
     _stages = new List<BsonDocument>();
 }
 internal abstract BsonValue TranslateExpressionToAggregateExpression <TSource, TResult>(
     Expression <Func <TSource, TResult> > expression,
     IBsonSerializer <TSource> sourceSerializer,
     IBsonSerializerRegistry serializerRegistry,
     ExpressionTranslationOptions translationOptions);
 private AggregateLanguageTranslator(ExpressionTranslationOptions translationOptions)
 {
     translationOptions = translationOptions ?? ExpressionTranslationOptions.Default;
     _stringTranslationMode = translationOptions.StringTranslationMode.GetValueOrDefault(AggregateStringTranslationMode.Bytes);
 }
 public static BsonValue Translate(Expression node, ExpressionTranslationOptions translationOptions)
 {
     var builder = new AggregateLanguageTranslator(translationOptions);
     return builder.TranslateValue(node);
 }
示例#19
0
        private ProjectedResult <TResult> Group <TKey, TResult>(Expression <Func <Root, TKey> > idProjector, Expression <Func <IGrouping <TKey, Root>, TResult> > groupProjector, ExpressionTranslationOptions translationOptions)
        {
            var queryable = __collection.AsQueryable()
                            .GroupBy(idProjector)
                            .Select(groupProjector);

            var collectionSerializer = (IBsonDocumentSerializer)BsonSerializer.LookupSerializer <Root>();
            var context  = TranslationContext.Create(queryable.Expression, collectionSerializer);
            var pipeline = ExpressionToPipelineTranslator.Translate(context, queryable.Expression);

            pipeline = AstPipelineOptimizer.Optimize(pipeline);

            var stages = pipeline.Stages.Select(s => s.Render()).Cast <BsonDocument>().ToList();

            stages.Insert(1, new BsonDocument("$sort", new BsonDocument("_id", 1))); // force a standard order for testing purposes
            var pipelineDefinition = new BsonDocumentStagePipelineDefinition <Root, TResult>(stages, outputSerializer: (IBsonSerializer <TResult>)pipeline.OutputSerializer);
            var results            = __collection.Aggregate(pipelineDefinition).ToList();

            stages.RemoveAt(1); // remove $sort added above for predictable testing
            return(new ProjectedResult <TResult>
            {
                Stages = stages,
                Value = results[0]
            });
        }
 internal abstract RenderedProjectionDefinition <TOutput> TranslateExpressionToProjection <TInput, TOutput>(
     Expression <Func <TInput, TOutput> > expression,
     IBsonSerializer <TInput> inputSerializer,
     IBsonSerializerRegistry serializerRegistry,
     ExpressionTranslationOptions translationOptions);
 internal abstract RenderedProjectionDefinition <TOutput> TranslateExpressionToGroupProjection <TInput, TKey, TOutput>(
     Expression <Func <TInput, TKey> > idExpression,
     Expression <Func <IGrouping <TKey, TInput>, TOutput> > groupExpression,
     IBsonSerializer <TInput> documentSerializer,
     IBsonSerializerRegistry serializerRegistry,
     ExpressionTranslationOptions translationOptions);
 internal abstract RenderedProjectionDefinition <TOutput> TranslateExpressionToBucketOutputProjection <TInput, TValue, TOutput>(
     Expression <Func <TInput, TValue> > valueExpression,
     Expression <Func <IGrouping <TValue, TInput>, TOutput> > outputExpression,
     IBsonSerializer <TInput> documentSerializer,
     IBsonSerializerRegistry serializerRegistry,
     ExpressionTranslationOptions translationOptions);
        public static QueryableTranslation Translate(Expression node, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
        {
            var translator = new QueryableTranslator(serializerRegistry, translationOptions);

            translator.Translate(node);

            var outputType    = translator._outputSerializer.ValueType;
            var modelType     = typeof(AggregateQueryableExecutionModel <>).MakeGenericType(outputType);
            var modelTypeInfo = modelType.GetTypeInfo();
            var outputSerializerInterfaceType = typeof(IBsonSerializer <>).MakeGenericType(new[] { outputType });
            var constructorParameterTypes     = new Type[] { typeof(IEnumerable <BsonDocument>), outputSerializerInterfaceType };
            var constructorInfo = modelTypeInfo.GetConstructors(BindingFlags.Instance | BindingFlags.NonPublic)
                                  .Where(c => c.GetParameters().Select(p => p.ParameterType).SequenceEqual(constructorParameterTypes))
                                  .Single();
            var constructorParameters = new object[] { translator._stages, translator._outputSerializer };
            var model = (QueryableExecutionModel)constructorInfo.Invoke(constructorParameters);

            return(new QueryableTranslation(model, translator._resultTransformer));
        }
 public QueryableTranslator(IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
 {
     _serializerRegistry = Ensure.IsNotNull(serializerRegistry, nameof(serializerRegistry));
     _translationOptions = translationOptions; // can be null
     _stages             = new List <BsonDocument>();
 }
        public static RenderedProjectionDefinition <TResult> Translate <TDocument, TResult>(Expression <Func <TDocument, TResult> > projector, IBsonSerializer <TDocument> parameterSerializer, IBsonSerializerRegistry serializerRegistry, ExpressionTranslationOptions translationOptions)
        {
            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, translationOptions);

            return(new RenderedProjectionDefinition <TResult>(projection, (IBsonSerializer <TResult>)projectionSerializer));
        }