示例#1
0
        // public static methods
        public static ExecutableQuery <TDocument, bool> Translate <TDocument>(MongoQueryProvider <TDocument> provider, TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.Is(QueryableMethod.All))
            {
                var sourceExpression = arguments[0];
                var pipeline         = ExpressionToPipelineTranslator.Translate(context, sourceExpression);

                var predicateLambda = ExpressionHelper.UnquoteLambda(arguments[1]);
                var predicateFilter = ExpressionToFilterTranslator.TranslateLambda(context, predicateLambda, parameterSerializer: pipeline.OutputSerializer);

                pipeline = pipeline.AddStages(
                    __outputSerializer,
                    AstStage.Match(AstFilter.Not(predicateFilter)),
                    AstStage.Limit(1),
                    AstStage.Project(
                        AstProject.ExcludeId(),
                        AstProject.Set("_v", BsonNull.Value)));

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

            throw new ExpressionNotSupportedException(expression);
        }
        public static AstFilter Translate(TranslationContext context, UnaryExpression expression)
        {
            var operandExpression = expression.Operand;

            if (operandExpression.Type == typeof(bool))
            {
                var operandTranslation = ExpressionToFilterTranslator.Translate(context, operandExpression);
                return(AstFilter.Not(operandTranslation));
            }

            throw new ExpressionNotSupportedException(expression);
        }
示例#3
0
        public static AstFilter Translate(TranslationContext context, MethodCallExpression expression)
        {
            if (AllWithContainsInPredicateMethodToFilterTranslator.CanTranslate(expression, out var arrayFieldExpression, out var arrayConstantExpression))
            {
                return(AllWithContainsInPredicateMethodToFilterTranslator.Translate(context, arrayFieldExpression, arrayConstantExpression));
            }

            if (AnyWithContainsInPredicateMethodToFilterTranslator.CanTranslate(expression, out arrayFieldExpression, out arrayConstantExpression))
            {
                return(AnyWithContainsInPredicateMethodToFilterTranslator.Translate(context, arrayFieldExpression, arrayConstantExpression));
            }

            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.IsOneOf(EnumerableMethod.All, EnumerableMethod.Any, EnumerableMethod.AnyWithPredicate))
            {
                var sourceExpression = arguments[0];
                var(field, filter) = FilteredEnumerableFilterFieldTranslator.Translate(context, sourceExpression);

                if (method.IsOneOf(EnumerableMethod.All, EnumerableMethod.AnyWithPredicate))
                {
                    var predicateLambda     = (LambdaExpression)arguments[1];
                    var parameterExpression = predicateLambda.Parameters.Single();
                    var elementSerializer   = ArraySerializerHelper.GetItemSerializer(field.Serializer);
                    var parameterSymbol     = context.CreateSymbol(parameterExpression, "@<elem>", elementSerializer); // @<elem> represents the implied element
                    var predicateContext    = context.WithSingleSymbol(parameterSymbol);                               // @<elem> is the only symbol visible inside an $elemMatch
                    var predicateFilter     = ExpressionToFilterTranslator.Translate(predicateContext, predicateLambda.Body, exprOk: false);

                    filter = AstFilter.Combine(filter, predicateFilter);
                }

                if (method.Is(EnumerableMethod.All))
                {
                    return(AstFilter.Not(AstFilter.ElemMatch(field, AstFilter.Not(filter))));
                }
                else
                {
                    if (filter == null)
                    {
                        return(AstFilter.And(AstFilter.Ne(field, BsonNull.Value), AstFilter.Not(AstFilter.Size(field, 0))));
                    }
                    else
                    {
                        return(AstFilter.ElemMatch(field, filter));
                    }
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
示例#4
0
        public static AstFilter Translate(TranslationContext context, BinaryExpression expression, Expression enumerableExpression, Expression sizeExpression)
        {
            var field = ExpressionToFilterFieldTranslator.Translate(context, enumerableExpression);

            if (TryConvertSizeExpressionToBsonValue(sizeExpression, out var size))
            {
                var compareCountFilter = AstFilter.Size(field, size);
                switch (expression.NodeType)
                {
                case ExpressionType.Equal: return(compareCountFilter);

                case ExpressionType.NotEqual: return(AstFilter.Not(compareCountFilter));
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
示例#5
0
        public static AstFilter Translate(TranslationContext context, BinaryExpression expression, UnaryExpression arrayLengthExpression, Expression sizeExpression)
        {
            if (arrayLengthExpression.NodeType == ExpressionType.ArrayLength)
            {
                var arrayExpression = arrayLengthExpression.Operand;
                var arrayField      = ExpressionToFilterFieldTranslator.Translate(context, arrayExpression);
                var size            = sizeExpression.GetConstantValue <int>(containingExpression: expression);

                switch (expression.NodeType)
                {
                case ExpressionType.Equal:
                    return(AstFilter.Size(arrayField, size));

                case ExpressionType.NotEqual:
                    return(AstFilter.Not(AstFilter.Size(arrayField, size)));
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
示例#6
0
        public static AstFilter Translate(TranslationContext context, BinaryExpression expression, BinaryExpression moduloExpression, Expression remainderExpression)
        {
            var fieldExpression = moduloExpression.Left;
            var field           = ExpressionToFilterFieldTranslator.Translate(context, fieldExpression);

            var       divisorExpression = moduloExpression.Right;
            BsonValue divisor;
            BsonValue remainder;

            if (divisorExpression.Type == typeof(decimal) && remainderExpression.Type == typeof(decimal))
            {
                divisor   = divisorExpression.GetConstantValue <decimal>(containingExpression: moduloExpression);
                remainder = remainderExpression.GetConstantValue <decimal>(containingExpression: expression);
            }
            else if (divisorExpression.Type == typeof(double) && remainderExpression.Type == typeof(double))
            {
                divisor   = divisorExpression.GetConstantValue <double>(containingExpression: moduloExpression);
                remainder = remainderExpression.GetConstantValue <double>(containingExpression: expression);
            }
            else if (divisorExpression.Type == typeof(float) && remainderExpression.Type == typeof(float))
            {
                divisor   = divisorExpression.GetConstantValue <float>(containingExpression: moduloExpression);
                remainder = remainderExpression.GetConstantValue <float>(containingExpression: expression);
            }
            else if (divisorExpression.Type == typeof(int) && remainderExpression.Type == typeof(int))
            {
                divisor   = divisorExpression.GetConstantValue <int>(containingExpression: moduloExpression);
                remainder = remainderExpression.GetConstantValue <int>(containingExpression: expression);
            }
            else if (divisorExpression.Type == typeof(long) && remainderExpression.Type == typeof(long))
            {
                divisor   = divisorExpression.GetConstantValue <long>(containingExpression: moduloExpression);
                remainder = remainderExpression.GetConstantValue <long>(containingExpression: expression);
            }
            else if (divisorExpression.Type == typeof(uint) && remainderExpression.Type == typeof(uint))
            {
                divisor   = divisorExpression.GetConstantValue <uint>(containingExpression: moduloExpression);
                remainder = remainderExpression.GetConstantValue <uint>(containingExpression: expression);
            }
            else if (divisorExpression.Type == typeof(ulong) && remainderExpression.Type == typeof(ulong))
            {
                divisor   = (long)divisorExpression.GetConstantValue <ulong>(containingExpression: moduloExpression);
                remainder = (long)remainderExpression.GetConstantValue <ulong>(containingExpression: expression);
            }
            else
            {
                throw new ExpressionNotSupportedException(expression);
            }

            var moduloComparisonAst = AstFilter.Mod(field, divisor, remainder);

            switch (expression.NodeType)
            {
            case ExpressionType.Equal:
                return(moduloComparisonAst);

            case ExpressionType.NotEqual:
                return(AstFilter.Not(moduloComparisonAst));
            }

            throw new ExpressionNotSupportedException(expression);
        }