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, MemberExpression expression) { var memberInfo = expression.Member; if (memberInfo is PropertyInfo propertyInfo) { if (propertyInfo.Is(NullableProperty.HasValue)) { var fieldExpression = expression.Expression; var field = ExpressionToFilterFieldTranslator.Translate(context, fieldExpression); return(AstFilter.Ne(field, BsonNull.Value)); } if (propertyInfo.PropertyType == typeof(bool)) { var field = ExpressionToFilterFieldTranslator.Translate(context, expression); return(AstFilter.Eq(field, true)); } } throw new ExpressionNotSupportedException(expression); }
private static AstFilter TranslateComparisonToBooleanConstant(TranslationContext context, Expression expression, Expression leftExpression, AstComparisonFilterOperator comparisonOperator, bool comparand) { var filter = ExpressionToFilterTranslator.Translate(context, leftExpression); if (filter is AstFieldOperationFilter fieldOperationFilter && fieldOperationFilter.Operation is AstComparisonFilterOperation comparisonOperation && comparisonOperation.Operator == AstComparisonFilterOperator.Eq && comparisonOperation.Value == true) { var field = fieldOperationFilter.Field; switch (comparisonOperator) { case AstComparisonFilterOperator.Eq: return(AstFilter.Eq(field, comparand)); case AstComparisonFilterOperator.Ne: return(AstFilter.Ne(field, comparand)); default: throw new ExpressionNotSupportedException(expression); } }