private Query VisitExpression(Expression expr, string prefix = null)
        {
            // Single: x.Active
            if (expr is MemberExpression && expr.Type == typeof(bool))
            {
                return(Query.EQ(this.GetField(expr, prefix), new BsonValue(true)));
            }
            // Not: !x.Active or !(x.Id == 1)
            else if (expr.NodeType == ExpressionType.Not)
            {
                var unary = expr as UnaryExpression;
                return(Query.Not(this.VisitExpression(unary.Operand, prefix)));
            }
            // Equals: x.Id == 1
            else if (expr.NodeType == ExpressionType.Equal)
            {
                var bin = expr as BinaryExpression;
                return(new QueryEquals(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left)));
            }
            // NotEquals: x.Id != 1
            else if (expr.NodeType == ExpressionType.NotEqual)
            {
                var bin = expr as BinaryExpression;
                return(Query.Not(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left)));
            }
            // LessThan: x.Id < 5
            else if (expr.NodeType == ExpressionType.LessThan)
            {
                var bin = expr as BinaryExpression;
                return(Query.LT(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left)));
            }
            // LessThanOrEqual: x.Id <= 5
            else if (expr.NodeType == ExpressionType.LessThanOrEqual)
            {
                var bin = expr as BinaryExpression;
                return(Query.LTE(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left)));
            }
            // GreaterThan: x.Id > 5
            else if (expr.NodeType == ExpressionType.GreaterThan)
            {
                var bin = expr as BinaryExpression;
                return(Query.GT(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left)));
            }
            // GreaterThanOrEqual: x.Id >= 5
            else if (expr.NodeType == ExpressionType.GreaterThanOrEqual)
            {
                var bin = expr as BinaryExpression;
                return(Query.GTE(this.GetField(bin.Left, prefix), this.VisitValue(bin.Right, bin.Left)));
            }
            // And: x.Id > 1 && x.Name == "John"
            else if (expr.NodeType == ExpressionType.AndAlso)
            {
                var bin   = expr as BinaryExpression;
                var left  = this.VisitExpression(bin.Left, prefix);
                var right = this.VisitExpression(bin.Right, prefix);

                return(Query.And(left, right));
            }
            // Or: x.Id == 1 || x.Name == "John"
            else if (expr.NodeType == ExpressionType.OrElse)
            {
                var bin   = expr as BinaryExpression;
                var left  = this.VisitExpression(bin.Left);
                var right = this.VisitExpression(bin.Right);

                return(Query.Or(left, right));
            }
            // Constant: do nothing (at this point it's useful only to PredicateBuilder)
            else if (expr.NodeType == ExpressionType.Constant)
            {
                var constant = expr as ConstantExpression;

                if (constant.Value is bool)
                {
                    var value = (bool)constant.Value;

                    return(value ? Query.All() : new QueryEmpty());
                }
            }
            // Invoke: call inner Lambda expression (used in PredicateBuilder)
            else if (expr.NodeType == ExpressionType.Invoke)
            {
                var invocation = expr as InvocationExpression;
                var lambda     = invocation.Expression as LambdaExpression;
                return(this.VisitExpression(lambda.Body));
            }
            // MethodCall: x.Name.StartsWith("John")
            else if (expr is MethodCallExpression)
            {
                var met    = expr as MethodCallExpression;
                var method = met.Method.Name;
#if NET35
                var type = met.Method.ReflectedType;
#else
                var type = met.Method.DeclaringType;
#endif
                var paramType = met.Arguments[0] is MemberExpression ?
                                (ExpressionType?)(met.Arguments[0] as MemberExpression).Expression.NodeType :
                                null;

                // StartsWith
                if (method == "StartsWith")
                {
                    var value = this.VisitValue(met.Arguments[0], null);

                    return(Query.StartsWith(this.GetField(met.Object, prefix), value));
                }
                // Equals
                else if (method == "Equals")
                {
                    var value = this.VisitValue(met.Arguments[0], null);

                    return(Query.EQ(this.GetField(met.Object, prefix), value));
                }
                // Contains (String): x.Name.Contains("auricio")
                else if (method == "Contains" && type == typeof(string))
                {
                    var value = this.VisitValue(met.Arguments[0], null);

                    return(Query.Contains(this.GetField(met.Object, prefix), value));
                }
                // Contains (Enumerable): x.ListNumber.Contains(2)
                else if (method == "Contains" && type == typeof(Enumerable))
                {
                    var field = this.GetField(met.Arguments[0], prefix);
                    var value = this.VisitValue(met.Arguments[1], null);

                    return(Query.EQ(field, value));
                }
                // Any (Enumerable): x.Customer.Any(z => z.Name.StartsWith("John"))
                else if (method == "Any" && type == typeof(Enumerable) && paramType == ExpressionType.Parameter)
                {
                    var field  = this.GetField(met.Arguments[0]);
                    var lambda = met.Arguments[1] as LambdaExpression;

                    return(this.VisitExpression(lambda.Body, field + "."));
                }
                // System.Linq.Enumerable methods (constant list items)
                else if (type == typeof(Enumerable))
                {
                    return(ParseEnumerableExpression(met));
                }
            }

            throw new NotImplementedException("Not implemented Linq expression");
        }
示例#2
0
        private Query VisitExpression(Expression expr)
        {
            if (expr.NodeType == ExpressionType.Equal) // ==
            {
                var bin = expr as BinaryExpression;
                return(new QueryEquals(this.VisitMember(bin.Left), this.VisitValue(bin.Right)));
            }
            else if (expr is MemberExpression && expr.Type == typeof(bool)) // x.Active
            {
                return(Query.EQ(this.VisitMember(expr), new BsonValue(true)));
            }
            else if (expr.NodeType == ExpressionType.NotEqual) // !=
            {
                var bin = expr as BinaryExpression;
                return(Query.Not(this.VisitMember(bin.Left), this.VisitValue(bin.Right)));
            }
            else if (expr.NodeType == ExpressionType.Not) // !x.Active
            {
                var bin = expr as UnaryExpression;
                return(Query.EQ(this.VisitMember(bin), new BsonValue(false)));
            }
            else if (expr.NodeType == ExpressionType.LessThan) // <
            {
                var bin = expr as BinaryExpression;
                return(Query.LT(this.VisitMember(bin.Left), this.VisitValue(bin.Right)));
            }
            else if (expr.NodeType == ExpressionType.LessThanOrEqual) // <=
            {
                var bin = expr as BinaryExpression;
                return(Query.LTE(this.VisitMember(bin.Left), this.VisitValue(bin.Right)));
            }
            else if (expr.NodeType == ExpressionType.GreaterThan) // >
            {
                var bin = expr as BinaryExpression;
                return(Query.GT(this.VisitMember(bin.Left), this.VisitValue(bin.Right)));
            }
            else if (expr.NodeType == ExpressionType.GreaterThanOrEqual) // >=
            {
                var bin = expr as BinaryExpression;
                return(Query.GTE(this.VisitMember(bin.Left), this.VisitValue(bin.Right)));
            }
            else if (expr is MethodCallExpression)
            {
                var met    = expr as MethodCallExpression;
                var method = met.Method.Name;

                // StartsWith
                if (method == "StartsWith")
                {
                    var value = this.VisitValue(met.Arguments[0]);

                    return(Query.StartsWith(this.VisitMember(met.Object), value));
                }
                // Contains
                else if (method == "Contains")
                {
                    var value = this.VisitValue(met.Arguments[0]);

                    return(Query.Contains(this.VisitMember(met.Object), value));
                }
                // Equals
                else if (method == "Equals")
                {
                    var value = this.VisitValue(met.Arguments[0]);

                    return(Query.EQ(this.VisitMember(met.Object), value));
                }
            }
            else if (expr is BinaryExpression && expr.NodeType == ExpressionType.AndAlso)
            {
                // AND
                var bin   = expr as BinaryExpression;
                var left  = this.VisitExpression(bin.Left);
                var right = this.VisitExpression(bin.Right);

                return(Query.And(left, right));
            }
            else if (expr is BinaryExpression && expr.NodeType == ExpressionType.OrElse)
            {
                // OR
                var bin   = expr as BinaryExpression;
                var left  = this.VisitExpression(bin.Left);
                var right = this.VisitExpression(bin.Right);

                return(Query.Or(left, right));
            }

            throw new NotImplementedException("Not implemented Linq expression");
        }
示例#3
0
        private QueryBuilder convertQuery(string _field, string _operator, string _value)
        {
            _operator = _operator.ToLower();
            bool   _ok    = false;
            Query  _query = null;
            string _msg   = string.Empty;

            switch (_operator)
            {
            case "all":                //int order = Ascending)
                //_query = Query.All();
                break;

            case "all_field":          //string field, int order = Ascending)
                //_query = Query.All();
                break;

            case "eq":                 //string field, BsonValue value)
                if (_value.IsNumeric())
                {
                    if (_value.IndexOf('.') != -1)
                    {
                        double _d = 0;
                        if (double.TryParse(_value, out _d))
                        {
                            _ok    = true;
                            _query = Query.EQ(_field, new BsonValue(_d));
                        }
                    }
                    else
                    {
                        int _val = 0;
                        if (int.TryParse(_value, out _val))
                        {
                            _ok    = true;
                            _query = Query.EQ(_field, new BsonValue(_val));
                        }
                    }
                }
                else
                {
                    _ok    = true;
                    _query = Query.EQ(_field, new BsonValue(_value));
                }
                break;

            case "lt":                 //string field, BsonValue value)
                _value = _value.Trim();
                if (_value.IsNumeric())
                {
                    _ok    = true;
                    _query = Query.LT(_field, new BsonValue(_value));
                }
                else
                {
                    _msg = "The field [" + _field + "] using operator [" + _operator + "] to compare value be not number: [" + _value + "]";
                }
                break;

            case "lte":                //string field, BsonValue value)
                _value = _value.Trim();
                if (_value.IsNumeric())
                {
                    _ok    = true;
                    _query = Query.LTE(_field, new BsonValue(_value));
                }
                else
                {
                    _msg = "The field [" + _field + "] using operator [" + _operator + "] to compare value be not number: [" + _value + "]";
                }
                break;

            case "gt":                 //string field, BsonValue value)
                _value = _value.Trim();
                if (_value.IsNumeric())
                {
                    _ok    = true;
                    _query = Query.GT(_field, new BsonValue(_value));
                }
                else
                {
                    _msg = "The field [" + _field + "] using operator [" + _operator + "] to compare value be not number: [" + _value + "]";
                }
                break;

            case "gte":                //string field, BsonValue value)
                _value = _value.Trim();
                if (_value.IsNumeric())
                {
                    _ok    = true;
                    _query = Query.GTE(_field, new BsonValue(_value));
                }
                else
                {
                    _msg = "The field [" + _field + "] using operator [" + _operator + "] to compare value be not number: [" + _value + "]";
                }
                break;

            case "between":            //string field, BsonValue start, BsonValue end, bool startEquals = true, bool endEquals = true)
                string[] a = _value.Split('|');
                if (a.Length == 2)
                {
                    string v1 = a[0].Trim(), v2 = a[1].Trim();
                    if (v1.IsNumeric() && v2.IsNumeric())
                    {
                        _ok    = true;
                        _query = Query.Between(_field, new BsonValue(v1), new BsonValue(v2));
                    }
                    else
                    {
                        _msg = "The field [" + _field + "] using operator [" + _operator + "] to compare value be not number: [" + _value + "]";
                    }
                }
                else
                {
                    _msg = "The field [" + _field + "] using operator [" + _operator + "] to compare value be not format: [ number_start | number_end ]";
                }
                break;

            case "start_with":         //string field, string value)
                _ok    = true;
                _query = Query.StartsWith(_field, _value);
                break;

            case "contains":           //string field, string value)
                _ok    = true;
                _query = Query.Contains(_field, _value);
                break;

            case "not":                //string field, BsonValue value)
                _ok    = true;
                _query = Query.Not(_field, new BsonValue(_value));
                break;

            //case "not_query":      //Query query, int order = Query.Ascending)
            //    _query = Query.All();
            //    break;
            //case "in_bson_array":  //string field, BsonArray value)
            //    _query = Query.All();
            //    break;
            case "in_array":           //string field, params BsonValue[] values)
                _value = _value.Trim();
                if (string.IsNullOrEmpty(_value))
                {
                    _msg = "The field [" + _field + "] using operator [" + _operator + "] to compare value be not format: [ number_start | number_end ]";
                }
                else
                {
                    _ok = true;
                    BsonValue[] a_in_array = _value.Split('|').Select(x => new BsonValue(x)).ToArray();
                    _query = Query.In(_field, a_in_array);
                }
                break;
                //case "in_ienumerable": //string field, IEnumerable<BsonValue> values)
                //    _query = Query.All();
                //    break;
            }
            return(new QueryBuilder()
            {
                Ok = _ok, Query = _query, Msg = _msg
            });
        }