private static IPredicate BuildPredicateTree(Func<string, IEntityField2> fieldGetter, Func<string, List<IEntityRelation>, IEntityField2> relatedFieldGetter, FilterNode filterNode, List<IEntityRelation> inferredRelationsList)
        {
            if (filterNode.NodeCount > 0)
            {
                if (filterNode.NodeType == FilterNodeType.Root && filterNode.Nodes.Count > 0)
                {
                    if (filterNode.NodeCount == 1)
                        return BuildPredicateTree(fieldGetter, relatedFieldGetter, filterNode.Nodes[0], inferredRelationsList);

                    var predicate = new PredicateExpression();
                    foreach (var childNode in filterNode.Nodes)
                    {
                        var newPredicate = BuildPredicateTree(fieldGetter, relatedFieldGetter, childNode, inferredRelationsList);
                        if (newPredicate != null)
                            predicate.AddWithAnd(newPredicate);
                    }
                    return predicate;
                }
                else if (filterNode.NodeType == FilterNodeType.AndExpression ||
                    filterNode.NodeType == FilterNodeType.OrExpression)
                {
                    var predicate = new PredicateExpression();
                    foreach (var childNode in filterNode.Nodes)
                    {
                        var newPredicate = BuildPredicateTree(fieldGetter, relatedFieldGetter, childNode, inferredRelationsList);
                        if (newPredicate != null)
                        {
                            if (filterNode.NodeType == FilterNodeType.OrExpression)
                                predicate.AddWithOr(newPredicate);
                            else
                                predicate.AddWithAnd(newPredicate);
                        }
                    }
                    return predicate;
                }
            }
            else if (filterNode.ElementCount > 0)
            {
                // convert elements to IPredicate
                var nodePredicate = BuildPredicateFromClauseNode(fieldGetter, relatedFieldGetter, filterNode, inferredRelationsList);
                if (nodePredicate != null)
                    return nodePredicate;
            }
            return null;
        }
Ejemplo n.º 2
0
        /*
         *  -> eq (equals any)
         *  -> neq (not equals any)
         *  -> eqc (equals any, case insensitive [on a case sensitive database])
         *  -> neqc (not equals any, case insensitive [on a case sensitive database])
         *  -> in (same as eq)
         *  -> nin (same as ne)
         *  -> lk (like)
         *  -> nlk (not like)
         *  -> nl (null)
         *  -> nnl (not null)
         *  -> gt (greater than)
         *  -> gte (greater than or equal to)
         *  -> lt (less than)
         *  -> lte (less than or equal to)
         *  -> ct (full text contains)
         *  -> ft (full text free text)
         *  -> bt (between)
         *  -> nbt (not between)
         */
        private static IPredicate BuildPredicateFromClauseNode(Func <string, IEntityField2> fieldGetter, Func <string, List <IEntityRelation>, IEntityField2> relatedFieldGetter, FilterNode filterNode, List <IEntityRelation> inferredRelationsList)
        {
            // there are always at least 2 elements
            if (filterNode.ElementCount < 2)
            {
                return(null);
            }

            var elements = filterNode.Elements;

            //TODO: may need to mess with relation aliases and join types in the future
            var relations = new List <IEntityRelation>();
            var field     = elements[0].IndexOf('.') == -1
                                      ? fieldGetter(elements[0])
                                      : relatedFieldGetter(elements[0], relations);

            if (field == null)
            {
                throw new ArgumentNullException("Unable to locate field " + elements[0]);
            }

            foreach (var relation in relations)
            {
                inferredRelationsList.AddIfNotExists(relation);
            }

            var comparisonOperatorStr = elements[1].ToLowerInvariant();

            var valueElements = elements.Skip(2).ToArray();
            var objElements   = new object[valueElements.Length];

            Action <string> throwINEEx = (s) =>
            {
                throw new ArgumentException(string.Format("Invalid number of elements in '{0}' filter clause", s));
            };

            string     objAlias;
            IPredicate predicate;

            switch (comparisonOperatorStr)
            {
            case ("bt"):     //between
            case ("nbt"):    //not between
                if (valueElements.Length < 2)
                {
                    throwINEEx(comparisonOperatorStr);
                }
                objElements[0] = ConvertStringToFieldValue(field, valueElements[0]);
                objElements[1] = ConvertStringToFieldValue(field, valueElements[1]);
                objAlias       = valueElements.Length == 3 ? valueElements[2] : null;
                predicate      = new FieldBetweenPredicate(field, null, objElements[0], objElements[1], objAlias, comparisonOperatorStr == "nbt");
                break;

            case ("in"):     //same as eq
            case ("nin"):    //same as ne
            case ("eq"):     //equals any
            case ("neq"):    //not equals any
            case ("eqc"):    //equals any, case insensitive [on a case sensitive database] - only 1 element per clause with this option
            case ("neqc"):   //not equals any, case insensitive [on a case sensitive database] - only 1 element per clause with this option
                if (valueElements.Length < 1)
                {
                    throwINEEx(comparisonOperatorStr);
                }
                for (int i = 0; i < valueElements.Length; i++)
                {
                    objElements[i] = ConvertStringToFieldValue(field, valueElements[i]);
                }
                if (objElements.Length == 1 || comparisonOperatorStr == "eqci" || comparisonOperatorStr == "neci")
                {
                    predicate = new FieldCompareValuePredicate(field, null, comparisonOperatorStr.StartsWith("n")
                                                                                    ? ComparisonOperator.NotEqual
                                                                                    : ComparisonOperator.Equal,
                                                               objElements[0])
                    {
                        CaseSensitiveCollation =
                            comparisonOperatorStr == "eqci" || comparisonOperatorStr == "neci"
                    };
                }
                else
                {
                    if (comparisonOperatorStr.StartsWith("n"))
                    {
                        predicate = (EntityField2)field != objElements;
                    }
                    else
                    {
                        predicate = (EntityField2)field == objElements;
                    }
                }
                break;

            case ("lk"):     //like
            case ("nlk"):    //not like
                if (valueElements.Length < 1)
                {
                    throwINEEx(comparisonOperatorStr);
                }
                objElements[0] = ConvertStringToFieldValue(field, valueElements[0].Replace('*', '%'));
                objAlias       = valueElements.Length == 2 ? valueElements[1] : null;
                predicate      = new FieldLikePredicate(field, null, objAlias, (string)objElements[0], comparisonOperatorStr == "nlk");
                break;

            case ("nl"):     //null
            case ("nnl"):    //not null
                predicate = new FieldCompareNullPredicate(field, null, null, comparisonOperatorStr == "nnl");
                break;

            case ("gt"):     //greater than)
            case ("gte"):    //greater than or equal to
            case ("lt"):     //less than
            case ("lte"):    //less than or equal to
                if (valueElements.Length < 1)
                {
                    throwINEEx(comparisonOperatorStr);
                }
                objElements[0] = ConvertStringToFieldValue(field, valueElements[0]);
                objAlias       = valueElements.Length == 2 ? valueElements[1] : null;
                var comparisonOperator = ComparisonOperator.GreaterThan;
                if (comparisonOperatorStr == "gte")
                {
                    comparisonOperator = ComparisonOperator.GreaterEqual;
                }
                else if (comparisonOperatorStr == "lt")
                {
                    comparisonOperator = ComparisonOperator.LesserThan;
                }
                else if (comparisonOperatorStr == "lte")
                {
                    comparisonOperator = ComparisonOperator.LessEqual;
                }
                predicate = new FieldCompareValuePredicate(field, null, comparisonOperator, objElements[0], objAlias);
                break;

            case ("ct"):     //full text contains
            case ("ft"):     //full text free text
                if (valueElements.Length < 1)
                {
                    throwINEEx(comparisonOperatorStr);
                }
                objElements[0] = valueElements[0];
                objAlias       = valueElements.Length == 2 ? valueElements[1] : null;
                predicate      = new FieldFullTextSearchPredicate(field, null, comparisonOperatorStr == "ct" ? FullTextSearchOperator.Contains : FullTextSearchOperator.Freetext, (string)objElements[0], objAlias);
                break;

            default:
                return(null);
            }
            return(predicate);
        }
        /*
            -> eq (equals any)
            -> neq (not equals any)
            -> eqc (equals any, case insensitive [on a case sensitive database])
            -> neqc (not equals any, case insensitive [on a case sensitive database])
            -> in (same as eq)
            -> nin (same as ne)
            -> lk (like)
            -> nlk (not like)
            -> nl (null)
            -> nnl (not null)
            -> gt (greater than)
            -> gte (greater than or equal to)
            -> lt (less than)
            -> lte (less than or equal to)
            -> ct (full text contains)
            -> ft (full text free text)
            -> bt (between)
            -> nbt (not between)
         */
        private static IPredicate BuildPredicateFromClauseNode(Func<string, IEntityField2> fieldGetter, Func<string, List<IEntityRelation>, IEntityField2> relatedFieldGetter, FilterNode filterNode, List<IEntityRelation> inferredRelationsList)
        {
            // there are always at least 2 elements
            if (filterNode.ElementCount < 2)
                return null;

            var elements = filterNode.Elements;

            //TODO: may need to mess with relation aliases and join types in the future
            var relations = new List<IEntityRelation>();
            var field = elements[0].IndexOf('.') == -1
                                      ? fieldGetter(elements[0])
                                      : relatedFieldGetter(elements[0], relations);
            if (field == null)
                throw new ArgumentNullException("Unable to locate field " + elements[0]);

            foreach (var relation in relations)
                inferredRelationsList.AddIfNotExists(relation);

            var comparisonOperatorStr = elements[1].ToLowerInvariant();

            var valueElements = elements.Skip(2).ToArray();
            var objElements = new object[valueElements.Length];

            Action<string> throwINEEx = (s) =>
            {
                throw new ArgumentException(string.Format("Invalid number of elements in '{0}' filter clause", s));
            };

            string objAlias;
            IPredicate predicate;
            switch (comparisonOperatorStr)
            {
                case ("bt"): //between
                case ("nbt"): //not between
                    if (valueElements.Length < 2) throwINEEx(comparisonOperatorStr);
                    objElements[0] = ConvertStringToFieldValue(field, valueElements[0]);
                    objElements[1] = ConvertStringToFieldValue(field, valueElements[1]);
                    objAlias = valueElements.Length == 3 ? valueElements[2] : null;
                    predicate = new FieldBetweenPredicate(field, null, objElements[0], objElements[1], objAlias, comparisonOperatorStr == "nbt");
                    break;
                case ("in"): //same as eq
                case ("nin"): //same as ne
                case ("eq"): //equals any
                case ("neq"): //not equals any
                case ("eqc"): //equals any, case insensitive [on a case sensitive database] - only 1 element per clause with this option
                case ("neqc"): //not equals any, case insensitive [on a case sensitive database] - only 1 element per clause with this option
                    if (valueElements.Length < 1) throwINEEx(comparisonOperatorStr);
                    for (int i = 0; i < valueElements.Length; i++)
                        objElements[i] = ConvertStringToFieldValue(field, valueElements[i]);
                    if (objElements.Length == 1 || comparisonOperatorStr == "eqci" || comparisonOperatorStr == "neci")
                    {
                        predicate = new FieldCompareValuePredicate(field, null, comparisonOperatorStr.StartsWith("n")
                                                                                    ? ComparisonOperator.NotEqual
                                                                                    : ComparisonOperator.Equal,
                                                                   objElements[0])
                        {
                            CaseSensitiveCollation =
                                comparisonOperatorStr == "eqci" || comparisonOperatorStr == "neci"
                        };
                    }
                    else
                    {
                        if (comparisonOperatorStr.StartsWith("n"))
                            predicate = (EntityField2)field != objElements;
                        else
                            predicate = (EntityField2)field == objElements;
                    }
                    break;
                case ("lk"): //like
                case ("nlk"): //not like
                    if (valueElements.Length < 1) throwINEEx(comparisonOperatorStr);
                    objElements[0] = ConvertStringToFieldValue(field, valueElements[0].Replace('*', '%'));
                    objAlias = valueElements.Length == 2 ? valueElements[1] : null;
                    predicate = new FieldLikePredicate(field, null, objAlias, (string)objElements[0], comparisonOperatorStr == "nlk");
                    break;
                case ("nl"): //null
                case ("nnl"): //not null
                    predicate = new FieldCompareNullPredicate(field, null, null, comparisonOperatorStr == "nnl");
                    break;
                case ("gt"): //greater than)
                case ("gte"): //greater than or equal to
                case ("lt"): //less than
                case ("lte"): //less than or equal to
                    if (valueElements.Length < 1) throwINEEx(comparisonOperatorStr);
                    objElements[0] = ConvertStringToFieldValue(field, valueElements[0]);
                    objAlias = valueElements.Length == 2 ? valueElements[1] : null;
                    var comparisonOperator = ComparisonOperator.GreaterThan;
                    if (comparisonOperatorStr == "gte") comparisonOperator = ComparisonOperator.GreaterEqual;
                    else if (comparisonOperatorStr == "lt") comparisonOperator = ComparisonOperator.LesserThan;
                    else if (comparisonOperatorStr == "lte") comparisonOperator = ComparisonOperator.LessEqual;
                    predicate = new FieldCompareValuePredicate(field, null, comparisonOperator, objElements[0], objAlias);
                    break;
                case ("ct"): //full text contains
                case ("ft"): //full text free text
                    if (valueElements.Length < 1) throwINEEx(comparisonOperatorStr);
                    objElements[0] = valueElements[0];
                    objAlias = valueElements.Length == 2 ? valueElements[1] : null;
                    predicate = new FieldFullTextSearchPredicate(field, null, comparisonOperatorStr == "ct" ? FullTextSearchOperator.Contains : FullTextSearchOperator.Freetext, (string)objElements[0], objAlias);
                    break;
                default:
                    return null;
            }
            return predicate;
        }
Ejemplo n.º 4
0
        private static IPredicate BuildPredicateTree(Func <string, IEntityField2> fieldGetter, Func <string, List <IEntityRelation>, IEntityField2> relatedFieldGetter, FilterNode filterNode, List <IEntityRelation> inferredRelationsList)
        {
            if (filterNode.NodeCount > 0)
            {
                if (filterNode.NodeType == FilterNodeType.Root && filterNode.Nodes.Count > 0)
                {
                    if (filterNode.NodeCount == 1)
                    {
                        return(BuildPredicateTree(fieldGetter, relatedFieldGetter, filterNode.Nodes[0], inferredRelationsList));
                    }

                    var predicate = new PredicateExpression();
                    foreach (var childNode in filterNode.Nodes)
                    {
                        var newPredicate = BuildPredicateTree(fieldGetter, relatedFieldGetter, childNode, inferredRelationsList);
                        if (newPredicate != null)
                        {
                            predicate.AddWithAnd(newPredicate);
                        }
                    }
                    return(predicate);
                }
                else if (filterNode.NodeType == FilterNodeType.AndExpression ||
                         filterNode.NodeType == FilterNodeType.OrExpression)
                {
                    var predicate = new PredicateExpression();
                    foreach (var childNode in filterNode.Nodes)
                    {
                        var newPredicate = BuildPredicateTree(fieldGetter, relatedFieldGetter, childNode, inferredRelationsList);
                        if (newPredicate != null)
                        {
                            if (filterNode.NodeType == FilterNodeType.OrExpression)
                            {
                                predicate.AddWithOr(newPredicate);
                            }
                            else
                            {
                                predicate.AddWithAnd(newPredicate);
                            }
                        }
                    }
                    return(predicate);
                }
            }
            else if (filterNode.ElementCount > 0)
            {
                // convert elements to IPredicate
                var nodePredicate = BuildPredicateFromClauseNode(fieldGetter, relatedFieldGetter, filterNode, inferredRelationsList);
                if (nodePredicate != null)
                {
                    return(nodePredicate);
                }
            }
            return(null);
        }