Пример #1
0
        private static QueryFilter ParseComparison <T>(BinaryExpression binaryExpression, ParameterExpression parameter)
        {
            var leftIsConstant  = ExpressionHelper.TryConvertToConstant(binaryExpression.Left, out var leftConstant);
            var rightIsConstant = ExpressionHelper.TryConvertToConstant(binaryExpression.Right, out var rightConstant);
            var leftIsProperty  = TryConvertToMember(binaryExpression.Left, out var leftMember);
            var rightIsProperty = TryConvertToMember(binaryExpression.Right, out var rightMember);

            if (!((leftIsConstant ^ rightIsConstant) || (leftIsProperty || rightIsProperty)))
            {
                throw new Exception($"{nameof(Parse)}: Expressions of type {binaryExpression.GetType()} with {nameof(binaryExpression.NodeType)}={binaryExpression.NodeType} must contain an expression that compiles to a constant value and a member expression. Found (sub-)expression: '{binaryExpression}'.");
            }

            var constantValue    = leftIsConstant ? leftConstant : rightConstant;
            var memberExpression = leftIsConstant ? rightMember : leftMember;

            var property = QueryInfo.EncodeMemberExpression(memberExpression, parameter);
            var constant = EncodeConstant(constantValue, constantValue.GetType());

            switch (binaryExpression.NodeType)
            {
            case ExpressionType.GreaterThan:
                return(GreaterThan(property, constant));

            case ExpressionType.GreaterThanOrEqual:
                return(GreaterThanEqual(property, constant));

            case ExpressionType.LessThan:
                return(LessThan(property, constant));

            case ExpressionType.LessThanOrEqual:
                return(LessThanEqual(property, constant));

            case ExpressionType.Equal:
                return(Exact(property, constant));

            default:
                throw new Exception($"{nameof(Parse)}: Expressions of type {binaryExpression.GetType()} with {nameof(binaryExpression.NodeType)}={binaryExpression.NodeType} are not supported yet. Found (sub-)expression: {binaryExpression}");
            }
        }
Пример #2
0
        private static QueryFilter[] Parse <T>(Expression exp, ParameterExpression parameter)
        {
            switch (exp)
            {
            case BinaryExpression binaryExpression:
                switch (binaryExpression.NodeType)
                {
                case ExpressionType.AndAlso:
                    return(Parse <T>(binaryExpression.Left, parameter)
                           .Concat(Parse <T>(binaryExpression.Right, parameter))
                           .ToArray());

                case ExpressionType.GreaterThan:
                case ExpressionType.GreaterThanOrEqual:
                case ExpressionType.LessThan:
                case ExpressionType.LessThanOrEqual:
                case ExpressionType.Equal:
                    return(new[] { ParseComparison <T>(binaryExpression, parameter) });

                default:
                    throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} with {nameof(binaryExpression.NodeType)}={binaryExpression.NodeType} are not supported yet. Found (sub-)expression: {exp}");
                }

            case MethodCallExpression methodCallExpression:
                if (methodCallExpression.Method.IsGenericMethod &&
                    methodCallExpression.Method.GetGenericMethodDefinition().Name == nameof(Enumerable.Contains) &&
                    methodCallExpression.Method.GetGenericMethodDefinition().GetParameters().Length == 2 &&
                    methodCallExpression.Method.GetGenericMethodDefinition().DeclaringType == typeof(Enumerable))
                {
                    if (!(ExpressionHelper.TryConvertToConstant(methodCallExpression.Arguments[0], out var constant)))
                    {
                        throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} that call {methodCallExpression.Method.Name} must be called on an expression that compiles to a constant value. Found (sub-)expression: {exp}");
                    }
                    if (!(TryConvertToMember(methodCallExpression.Arguments[1], out var memberExpression)))
                    {
                        throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} that call {methodCallExpression.Method.Name} must be called with a member expression as argument. Found (sub-)expression: {exp}");
                    }

                    return(new[] { In(QueryInfo.EncodeMemberExpression(memberExpression, parameter), EncodeConstantCollection(constant)) });
                }
                if (methodCallExpression.Method.Name == nameof(string.StartsWith) &&
                    methodCallExpression.Method.GetParameters().Length == 1 &&
                    methodCallExpression.Method.DeclaringType == typeof(string))
                {
                    if (!(ExpressionHelper.TryConvertToConstant(methodCallExpression.Arguments[0], out var constant)))
                    {
                        throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} that call {methodCallExpression.Method.Name} must be called with an expression that compiles to a constant value as argument. Found (sub-)expression: {exp}");
                    }
                    if (!(TryConvertToMember(methodCallExpression.Object, out var memberExpression)))
                    {
                        throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} that call {methodCallExpression.Method.Name} must be called on a member expression. Found (sub-)expression: {exp}");
                    }

                    return(new[] { FreeText(QueryInfo.EncodeMemberExpression(memberExpression, parameter), EncodeConstant(constant, constant.GetType()) + "*") });
                }
                if (methodCallExpression.Method.Name == nameof(string.EndsWith) &&
                    methodCallExpression.Method.GetParameters().Length == 1 &&
                    methodCallExpression.Method.DeclaringType == typeof(string))
                {
                    if (!(ExpressionHelper.TryConvertToConstant(methodCallExpression.Arguments[0], out var constant)))
                    {
                        throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} that call {methodCallExpression.Method.Name} must be called with an expression that compiles to a constant value as argument. Found (sub-)expression: {exp}");
                    }
                    if (!(TryConvertToMember(methodCallExpression.Object, out var memberExpression)))
                    {
                        throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} that call {methodCallExpression.Method.Name} must be called on a member expression. Found (sub-)expression: {exp}");
                    }

                    return(new[] { FreeText(QueryInfo.EncodeMemberExpression(memberExpression, parameter), "*" + EncodeConstant(constant, constant.GetType())) });
                }
                if (methodCallExpression.Method.Name == nameof(string.Contains) &&
                    methodCallExpression.Method.GetParameters().Length == 1 &&
                    methodCallExpression.Method.DeclaringType == typeof(string))
                {
                    if (!(ExpressionHelper.TryConvertToConstant(methodCallExpression.Arguments[0], out var constant)))
                    {
                        throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} that call {methodCallExpression.Method.Name} must be called with an expression that compiles to a constant value as argument. Found (sub-)expression: {exp}");
                    }
                    if (!(TryConvertToMember(methodCallExpression.Object, out var memberExpression)))
                    {
                        throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} that call {methodCallExpression.Method.Name} must be called on a member expression. Found (sub-)expression: {exp}");
                    }

                    return(new[] { FreeText(QueryInfo.EncodeMemberExpression(memberExpression, parameter), "*" + EncodeConstant(constant, constant.GetType()) + "*") });
                }
                throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} are only partially supported. The found call is not supported. Found (sub-)expression: {exp}");

            default:
                throw new Exception($"{nameof(Parse)}: Expressions of type {exp.GetType()} are not supported yet. Found (sub-)expression: {exp}");
            }
        }
Пример #3
0
 public QuerySortProperty(Expression <Func <T, object> > propertyExpression, bool ascending = true)
     : base(QueryInfo.EncodeMemberExpression(propertyExpression.Body, propertyExpression.Parameters[0]), ascending)
 {
 }