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