// public static methods
        public static ExecutableQuery <TDocument, TOutput> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.IsOneOf(__averageMethods))
            {
                var sourceExpression = arguments[0];
                var pipeline         = ExpressionToPipelineTranslator.Translate(context, sourceExpression);
                var sourceSerializer = pipeline.OutputSerializer;

                AstExpression valueExpression;
                if (method.IsOneOf(__averageWithSelectorMethods))
                {
                    var selectorLambda      = ExpressionHelper.UnquoteLambda(arguments[1]);
                    var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true);
                    valueExpression = selectorTranslation.Ast;
                }
                else
                {
                    Ensure.That(sourceSerializer is IWrappedValueSerializer, "Expected sourceSerializer to be an IWrappedValueSerializer.", nameof(sourceSerializer));
                    var root = AstExpression.Var("ROOT", isCurrent: true);
                    valueExpression = AstExpression.GetField(root, "_v");
                }

                IBsonSerializer outputValueSerializer = expression.GetResultType() switch
                {
                    Type t when t == typeof(int) => new Int32Serializer(),
                    Type t when t == typeof(long) => new Int64Serializer(),
                    Type t when t == typeof(float) => new SingleSerializer(),
                    Type t when t == typeof(double) => new DoubleSerializer(),
                    Type t when t == typeof(decimal) => new DecimalSerializer(),
                    Type {
                        IsConstructedGenericType : true
                    } t when t.GetGenericTypeDefinition() == typeof(Nullable <>) => (IBsonSerializer)Activator.CreateInstance(typeof(NullableSerializer <>).MakeGenericType(t.GenericTypeArguments[0])),
                    _ => throw new ExpressionNotSupportedException(expression)
                };
                var outputWrappedValueSerializer = WrappedValueSerializer.Create("_v", outputValueSerializer);

                pipeline = pipeline.AddStages(
                    outputWrappedValueSerializer,
                    AstStage.Group(
                        id: BsonNull.Value,
                        fields: AstExpression.AccumulatorField("_v", AstAccumulatorOperator.Avg, valueExpression)),
                    AstStage.Project(AstProject.ExcludeId()));

                return(ExecutableQuery.Create(
                           provider.Collection,
                           provider.Options,
                           pipeline,
                           __finalizer));
            }

            throw new ExpressionNotSupportedException(expression);
        }
    }
        // public static methods
        public static ExecutableQuery <TDocument, TOutput> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.IsOneOf(__standardDeviationMethods))
            {
                var sourceExpression = ConvertHelper.RemoveConvertToMongoQueryable(arguments[0]);
                var pipeline         = ExpressionToPipelineTranslator.Translate(context, sourceExpression);
                var sourceSerializer = pipeline.OutputSerializer;

                var           stdDevOperator = method.IsOneOf(__standardDeviationPopulationMethods) ? AstAccumulatorOperator.StdDevPop : AstAccumulatorOperator.StdDevSamp;
                AstExpression valueAst;
                if (method.IsOneOf(__standardDeviationWithSelectorMethods))
                {
                    var selectorLambda      = ExpressionHelper.UnquoteLambda(arguments[1]);
                    var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true);
                    valueAst = selectorTranslation.Ast;
                }
                else
                {
                    var root = AstExpression.Var("ROOT", isCurrent: true);
                    valueAst = AstExpression.GetField(root, "_v");
                }
                var outputValueType              = expression.GetResultType();
                var outputValueSerializer        = BsonSerializer.LookupSerializer(outputValueType);
                var outputWrappedValueSerializer = WrappedValueSerializer.Create("_v", outputValueSerializer);

                pipeline = pipeline.AddStages(
                    outputWrappedValueSerializer,
                    AstStage.Group(
                        id: BsonNull.Value,
                        AstExpression.AccumulatorField("_v", stdDevOperator, valueAst)),
                    AstStage.Project(AstProject.ExcludeId()));

                var finalizer = method.IsOneOf(__standardDeviationNullableMethods) ? __singleOrDefaultFinalizer : __singleFinalizer;

                return(ExecutableQuery.Create(
                           provider.Collection,
                           provider.Options,
                           pipeline,
                           finalizer));
            }

            throw new ExpressionNotSupportedException(expression);
        }
Exemple #3
0
        // public static methods
        public static ExecutableQuery <TDocument, TOutput> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.IsOneOf(__sumMethods))
            {
                var sourceExpression = arguments[0];
                var pipeline         = ExpressionToPipelineTranslator.Translate(context, sourceExpression);
                var sourceSerializer = pipeline.OutputSerializer;

                AstExpression valueAst;
                if (method.IsOneOf(__sumWithSelectorMethods))
                {
                    var selectorLambda      = ExpressionHelper.UnquoteLambda(arguments[1]);
                    var selectorTranslation = ExpressionToAggregationExpressionTranslator.TranslateLambdaBody(context, selectorLambda, sourceSerializer, asRoot: true);
                    valueAst = selectorTranslation.Ast;
                }
                else
                {
                    Ensure.That(sourceSerializer is IWrappedValueSerializer, "Expected sourceSerializer to be an IWrappedValueSerializer.", nameof(sourceSerializer));
                    var rootVar = AstExpression.Var("ROOT", isCurrent: true);
                    valueAst = AstExpression.GetField(rootVar, "_v");
                }

                var outputValueType              = expression.GetResultType();
                var outputValueSerializer        = BsonSerializer.LookupSerializer(outputValueType);
                var outputWrappedValueSerializer = WrappedValueSerializer.Create("_v", outputValueSerializer);

                pipeline = pipeline.AddStages(
                    outputWrappedValueSerializer,
                    AstStage.Group(
                        id: BsonNull.Value,
                        fields: AstExpression.AccumulatorField("_v", AstAccumulatorOperator.Sum, valueAst)),
                    AstStage.Project(AstProject.ExcludeId()));

                return(ExecutableQuery.Create(
                           provider.Collection,
                           provider.Options,
                           pipeline,
                           __finalizer));
            }

            throw new ExpressionNotSupportedException(expression);
        }