Exemplo n.º 1
0
        public static AstFilterField Translate(TranslationContext context, MemberExpression memberExpression)
        {
            var fieldExpression     = ConvertHelper.RemoveConvertToInterface(memberExpression.Expression);
            var field               = ExpressionToFilterFieldTranslator.Translate(context, fieldExpression);
            var fieldSerializer     = field.Serializer;
            var fieldSerializerType = fieldSerializer.GetType();

            if (fieldSerializer is IBsonDocumentSerializer documentSerializer &&
                documentSerializer.TryGetMemberSerializationInfo(memberExpression.Member.Name, out BsonSerializationInfo memberSerializationInfo))
            {
                var subFieldName       = memberSerializationInfo.ElementName;
                var subFieldSerializer = memberSerializationInfo.Serializer;
                return(field.SubField(subFieldName, subFieldSerializer));
            }

            if (memberExpression.Expression.Type.IsConstructedGenericType &&
                memberExpression.Expression.Type.GetGenericTypeDefinition() == typeof(Nullable <>) &&
                memberExpression.Member.Name == "Value" &&
                fieldSerializerType.IsConstructedGenericType &&
                fieldSerializerType.GetGenericTypeDefinition() == typeof(NullableSerializer <>))
            {
                var valueSerializer = ((IChildSerializerConfigurable)fieldSerializer).ChildSerializer;
                return(AstFilter.Field(field.Path, valueSerializer));
            }

            throw new ExpressionNotSupportedException(memberExpression);
        }
Exemplo n.º 2
0
        public static AstFilterField Translate(TranslationContext context, BinaryExpression expression)
        {
            if (expression.NodeType == ExpressionType.ArrayIndex)
            {
                var arrayExpression = expression.Left;
                var arrayField      = ExpressionToFilterFieldTranslator.Translate(context, arrayExpression);
                var indexExpression = expression.Right;
                var index           = indexExpression.GetConstantValue <int>(containingExpression: expression);

                if (index < 0)
                {
                    var reason = "negative indexes are not valid";
                    if (index == -1)
                    {
                        reason += ". To use the positional operator $ use FirstMatchingElement instead of an index value of -1"; // closing period is added by exception
                    }
                    throw new ExpressionNotSupportedException(expression, because: reason);
                }

                var itemSerializer = ArraySerializerHelper.GetItemSerializer(arrayField.Serializer);
                return(arrayField.SubField(index.ToString(), itemSerializer));
            }

            throw new ExpressionNotSupportedException(expression);
        }
Exemplo n.º 3
0
        public static AstFilterField Translate(TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.Is(MongoEnumerableMethod.AllMatchingElements))
            {
                var sourceExpression = arguments[0];
                var field            = ExpressionToFilterFieldTranslator.Translate(context, sourceExpression);

                var identifierExpression = arguments[1];
                var identifier           = identifierExpression.GetConstantValue <string>(containingExpression: expression);

                if (identifier == "")
                {
                    throw new ExpressionNotSupportedException(expression, because: "identifier cannot be an empty string.");
                }

                if (field.Serializer is IBsonArraySerializer arraySerializer &&
                    arraySerializer.TryGetItemSerializationInfo(out var itemSerializationInfo))
                {
                    var itemSerializer = itemSerializationInfo.Serializer;
                    return(field.SubField($"$[{identifier}]", itemSerializer));
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
        public static AstFilterField Translate(TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.Is(EnumerableMethod.ElementAt))
            {
                var sourceExpression = arguments[0];
                var field            = ExpressionToFilterFieldTranslator.Translate(context, sourceExpression);

                var indexExpression = arguments[1];
                var index           = indexExpression.GetConstantValue <int>(containingExpression: expression);

                if (index < 0)
                {
                    var reason = "negative indexes are not valid";
                    if (index == -1)
                    {
                        reason += ". To use the positional operator $ use FirstMatchingElement instead of an index value of -1"; // closing period is added by exception
                    }
                    throw new ExpressionNotSupportedException(expression, because: reason);
                }

                if (field.Serializer is IBsonArraySerializer arraySerializer &&
                    arraySerializer.TryGetItemSerializationInfo(out var itemSerializationInfo))
                {
                    var itemSerializer = itemSerializationInfo.Serializer;
                    return(field.SubField(index.ToString(), itemSerializer));
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
        public static AstFilterField Translate(TranslationContext context, BinaryExpression expression)
        {
            if (expression.NodeType == ExpressionType.ArrayIndex)
            {
                var arrayExpression = expression.Left;
                var arrayField      = ExpressionToFilterFieldTranslator.Translate(context, arrayExpression);
                var indexExpression = expression.Right;
                var index           = indexExpression.GetConstantValue <int>(containingExpression: expression);
                var itemSerializer  = ArraySerializerHelper.GetItemSerializer(arrayField.Serializer);
                return(arrayField.SubField(index.ToString(), itemSerializer));
            }

            throw new ExpressionNotSupportedException(expression);
        }
Exemplo n.º 6
0
        private static AstFilterField TranslateWithIntIndex(TranslationContext context, MethodCallExpression expression, MethodInfo method, Expression fieldExpression, int index)
        {
            var field = ExpressionToFilterFieldTranslator.TranslateEnumerable(context, fieldExpression);

            if (field.Serializer is IBsonArraySerializer arraySerializer &&
                arraySerializer.TryGetItemSerializationInfo(out var itemSerializationInfo))
            {
                var itemSerializer = itemSerializationInfo.Serializer;
                if (method.ReturnType.IsAssignableFrom(itemSerializer.ValueType))
                {
                    return(field.SubField(index.ToString(), itemSerializer));
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
        public static AstFilterField Translate(TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.Is(MongoEnumerableMethod.AllElements))
            {
                var sourceExpression = arguments[0];
                var field            = ExpressionToFilterFieldTranslator.Translate(context, sourceExpression);

                if (field.Serializer is IBsonArraySerializer arraySerializer &&
                    arraySerializer.TryGetItemSerializationInfo(out var itemSerializationInfo))
                {
                    var itemSerializer = itemSerializationInfo.Serializer;
                    return(field.SubField($"$[]", itemSerializer));
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
Exemplo n.º 8
0
        private static AstFilterField TranslateWithStringIndex(TranslationContext context, MethodCallExpression expression, MethodInfo method, Expression fieldExpression, string key)
        {
            var field = ExpressionToFilterFieldTranslator.Translate(context, fieldExpression);

            if (typeof(BsonValue).IsAssignableFrom(field.Serializer.ValueType))
            {
                var valueSerializer = BsonValueSerializer.Instance;
                return(field.SubField(key, valueSerializer));
            }

            if (field.Serializer is IBsonDictionarySerializer dictionarySerializer &&
                dictionarySerializer.DictionaryRepresentation == DictionaryRepresentation.Document)
            {
                var valueSerializer = dictionarySerializer.ValueSerializer;
                if (method.ReturnType.IsAssignableFrom(valueSerializer.ValueType))
                {
                    return(field.SubField(key, valueSerializer));
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
        public static AstFilterField Translate(TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.IsStatic &&
                method.Name == "First" &&
                arguments.Count == 1)
            {
                var enumerableFieldAst = ExpressionToFilterFieldTranslator.TranslateEnumerable(context, arguments[0]);
                if (enumerableFieldAst.Serializer is IBsonArraySerializer arraySerializer &&
                    arraySerializer.TryGetItemSerializationInfo(out var itemSerializationInfo))
                {
                    var itemSerializer = itemSerializationInfo.Serializer;
                    if (method.ReturnType.IsAssignableFrom(itemSerializer.ValueType))
                    {
                        return(enumerableFieldAst.SubField("0", itemSerializer));
                    }
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
        public static AstFilterField Translate(TranslationContext context, MethodCallExpression expression)
        {
            var method    = expression.Method;
            var arguments = expression.Arguments;

            if (method.Is(EnumerableMethod.ElementAt))
            {
                var sourceExpression = arguments[0];
                var field            = ExpressionToFilterFieldTranslator.Translate(context, sourceExpression);

                var indexExpression = arguments[1];
                var index           = indexExpression.GetConstantValue <int>(containingExpression: expression);

                if (field.Serializer is IBsonArraySerializer arraySerializer &&
                    arraySerializer.TryGetItemSerializationInfo(out var itemSerializationInfo))
                {
                    var itemSerializer = itemSerializationInfo.Serializer;
                    return(field.SubField(index.ToString(), itemSerializer));
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }
        public static AstFilterField Translate(TranslationContext context, UnaryExpression expression)
        {
            if (expression.NodeType == ExpressionType.Convert)
            {
                var field           = ExpressionToFilterFieldTranslator.Translate(context, expression.Operand);
                var fieldSerializer = field.Serializer;
                var fieldType       = fieldSerializer.ValueType;
                var targetType      = expression.Type;

                if (fieldType.IsEnum())
                {
                    var enumType           = fieldType;
                    var enumUnderlyingType = enumType.GetEnumUnderlyingType();
                    if (targetType == enumUnderlyingType)
                    {
                        var enumUnderlyingTypeSerializer = EnumUnderlyingTypeSerializer.Create(fieldSerializer);
                        return(AstFilter.Field(field.Path, enumUnderlyingTypeSerializer));
                    }
                }

                if (IsNumericType(targetType))
                {
                    IBsonSerializer targetTypeSerializer = expression.Type switch
                    {
                        Type t when t == typeof(byte) => new ByteSerializer(),
                        Type t when t == typeof(short) => new Int16Serializer(),
                        Type t when t == typeof(ushort) => new UInt16Serializer(),
                        Type t when t == typeof(int) => new Int32Serializer(),
                        Type t when t == typeof(uint) => new UInt32Serializer(),
                        Type t when t == typeof(long) => new Int64Serializer(),
                        Type t when t == typeof(ulong) => new UInt64Serializer(),
                        Type t when t == typeof(float) => new SingleSerializer(),
                        Type t when t == typeof(double) => new DoubleSerializer(),
                        Type t when t == typeof(decimal) => new DecimalSerializer(),
                        _ => throw new ExpressionNotSupportedException(expression)
                    };
                    if (fieldSerializer is IRepresentationConfigurable representationConfigurableFieldSerializer &&
                        targetTypeSerializer is IRepresentationConfigurable representationConfigurableTargetTypeSerializer)
                    {
                        var fieldRepresentation = representationConfigurableFieldSerializer.Representation;
                        if (fieldRepresentation == BsonType.String)
                        {
                            targetTypeSerializer = representationConfigurableTargetTypeSerializer.WithRepresentation(fieldRepresentation);
                        }
                    }
                    if (fieldSerializer is IRepresentationConverterConfigurable converterConfigurableFieldSerializer &&
                        targetTypeSerializer is IRepresentationConverterConfigurable converterConfigurableTargetTypeSerializer)
                    {
                        targetTypeSerializer = converterConfigurableTargetTypeSerializer.WithConverter(converterConfigurableFieldSerializer.Converter);
                    }
                    return(AstFilter.Field(field.Path, targetTypeSerializer));
                }

                if (targetType.IsConstructedGenericType &&
                    targetType.GetGenericTypeDefinition() == typeof(Nullable <>))
                {
                    var nullableValueType = targetType.GetGenericArguments()[0];
                    if (nullableValueType == fieldType)
                    {
                        var nullableSerializerType = typeof(NullableSerializer <>).MakeGenericType(nullableValueType);
                        var nullableSerializer     = (IBsonSerializer)Activator.CreateInstance(nullableSerializerType, fieldSerializer);
                        return(AstFilter.Field(field.Path, nullableSerializer));
                    }

                    if (fieldType.IsConstructedGenericType &&
                        fieldType.GetGenericTypeDefinition() == typeof(Nullable <>))
                    {
                        var fieldValueType = fieldType.GetGenericArguments()[0];
                        if (fieldValueType.IsEnum())
                        {
                            var enumUnderlyingType = fieldValueType.GetEnumUnderlyingType();
                            if (nullableValueType == enumUnderlyingType)
                            {
                                var fieldSerializerType = fieldSerializer.GetType();
                                if (fieldSerializerType.IsConstructedGenericType &&
                                    fieldSerializerType.GetGenericTypeDefinition() == typeof(NullableSerializer <>))
                                {
                                    var enumSerializer = ((IChildSerializerConfigurable)fieldSerializer).ChildSerializer;
                                    var enumUnderlyingTypeSerializer = EnumUnderlyingTypeSerializer.Create(enumSerializer);
                                    var nullableSerializerType       = typeof(NullableSerializer <>).MakeGenericType(nullableValueType);
                                    var nullableSerializer           = (IBsonSerializer)Activator.CreateInstance(nullableSerializerType, enumUnderlyingTypeSerializer);
                                    return(AstFilter.Field(field.Path, nullableSerializer));
                                }
                            }
                        }
                    }
                }
            }

            throw new ExpressionNotSupportedException(expression);
        }