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) { if (expression.NodeType == ExpressionType.And || expression.NodeType == ExpressionType.AndAlso) { var leftExpression = expression.Left; var rightExpression = expression.Right; if (leftExpression.Type == typeof(bool) && rightExpression.Type == typeof(bool)) { var leftTranslation = ExpressionToFilterTranslator.Translate(context, leftExpression); var rightTranslation = ExpressionToFilterTranslator.Translate(context, rightExpression); return(AstFilter.And(leftTranslation, rightTranslation)); } } throw new ExpressionNotSupportedException(expression); }