示例#1
0
        public override void VisitWhereClause(WhereClause whereClause, QueryModel queryModel, int index)
        {
            if (whereClause.Predicate is BinaryExpression expression)
            {
                VisitBinaryExpression(expression, RootExpression);
            }
            else
            {
                if (whereClause.Predicate is SubQueryExpression subQuery)
                {
                    ExplainAndExpression andExpression;

                    if (!RootExpression.MultipleWhereClauses)
                    {
                        andExpression = new ExplainAndExpression();
                        RootExpression.Elements.Add(andExpression);
                    }
                    else // multiple where clauses are joined by AND
                    {
                        andExpression = RootExpression.Elements[0];
                    }

                    var leaf = new LeafExpression();
                    andExpression.Elements.Add(leaf);

                    VisitContainsExpression(subQuery, leaf);
                }
                else if (whereClause.Predicate is MethodCallExpression call)
                {
                    ExplainAndExpression andExpression;

                    if (!RootExpression.MultipleWhereClauses)
                    {
                        andExpression = new ExplainAndExpression();
                        RootExpression.Elements.Add(andExpression);
                    }
                    else // multiple where clauses are joined by AND
                    {
                        andExpression = RootExpression.Elements[0];
                    }

                    var leaf = CallToLeafExpression(call);
                    andExpression.Elements.Add(leaf);
                }
                else if (whereClause.Predicate.NodeType != ExpressionType.Constant)
                {
                    throw new NotSupportedException("query too complex");
                }
            }


            RootExpression.MultipleWhereClauses = true;

            base.VisitWhereClause(whereClause, queryModel, index);
        }
示例#2
0
        private void VisitAndExpression(BinaryExpression binaryExpression, ExplainAndExpression andExpression)
        {
            if (IsLeafExpression(binaryExpression.Left))
            {
                andExpression.Elements.Add(VisitLeafExpression((BinaryExpression)binaryExpression.Left));
            }
            else if (binaryExpression.Left.NodeType == ExpressionType.AndAlso)
            {
                VisitAndExpression((BinaryExpression)binaryExpression.Left, andExpression);
            }
            else if (binaryExpression.Left.NodeType == ExpressionType.Extension)
            {
                if (binaryExpression.Left is SubQueryExpression subQuery)
                {
                    var leaf = new LeafExpression();
                    andExpression.Elements.Add(leaf);
                    VisitContainsExpression(subQuery, leaf);
                }
            }
            else if (binaryExpression.Left is MethodCallExpression callExpression)
            {
                andExpression.Elements.Add(CallToLeafExpression(callExpression));
            }
            else
            {
                throw new NotSupportedException("ExplainExpression too complex");
            }

            if (IsLeafExpression(binaryExpression.Right))
            {
                andExpression.Elements.Add(VisitLeafExpression((BinaryExpression)binaryExpression.Right));
            }
            else if (binaryExpression.Right.NodeType == ExpressionType.Extension)
            {
                if (binaryExpression.Right is SubQueryExpression subQuery)
                {
                    var leaf = new LeafExpression();
                    andExpression.Elements.Add(leaf);
                    VisitContainsExpression(subQuery, leaf);
                }
            }
            else if (binaryExpression.Right is MethodCallExpression callExpression)
            {
                andExpression.Elements.Add(CallToLeafExpression(callExpression));
            }
            else
            {
                throw new NotSupportedException("ExplainExpression too complex");
            }
        }
示例#3
0
        private void VisitBinaryExpression(BinaryExpression binaryExpression, ExplainOrExpression rootExpression)
        {
            // manage AND expressions
            if (binaryExpression.NodeType == ExpressionType.AndAlso)
            {
                var andExpression = new ExplainAndExpression();
                rootExpression.Elements.Add(andExpression);

                VisitAndExpression(binaryExpression, andExpression);
            }

            // manage OR expressions
            else if (binaryExpression.NodeType == ExpressionType.OrElse)
            {
                VisitOrExpression(binaryExpression, rootExpression);
            }

            // manage simple expressions like a > 10
            else if (IsLeafExpression(binaryExpression))
            {
                ExplainAndExpression andExpression;

                if (!rootExpression.MultipleWhereClauses)
                {
                    andExpression = new ExplainAndExpression();
                    rootExpression.Elements.Add(andExpression);
                }
                else // if multiple where clauses consider them as expressions linked by AND
                {
                    andExpression = rootExpression.Elements[0];
                }


                andExpression.Elements.Add(VisitLeafExpression(binaryExpression));
            }
            else
            {
                throw new NotSupportedException("ExplainExpression too complex");
            }
        }
示例#4
0
        //TODO add unit test for OR expression with Contains
        /// <summary>
        ///     OR expression can be present only at root level
        /// </summary>
        /// <param name="binaryExpression"></param>
        /// <param name="rootExpression"></param>
        private void VisitOrExpression(BinaryExpression binaryExpression, ExplainOrExpression rootExpression)
        {
            // visit left part
            if (IsLeafExpression(binaryExpression.Left))
            {
                var andExpression = new ExplainAndExpression();
                rootExpression.Elements.Add(andExpression);

                andExpression.Elements.Add(VisitLeafExpression((BinaryExpression)binaryExpression.Left));
            }
            else if (binaryExpression.Left.NodeType == ExpressionType.AndAlso)
            {
                var andExpression = new ExplainAndExpression();
                rootExpression.Elements.Add(andExpression);
                VisitAndExpression((BinaryExpression)binaryExpression.Left, andExpression);
            }
            else if (binaryExpression.Left.NodeType == ExpressionType.Extension)
            {
                if (binaryExpression.Left is SubQueryExpression subQuery)
                {
                    ExplainAndExpression andExpression;

                    if (!rootExpression.MultipleWhereClauses)
                    {
                        andExpression = new ExplainAndExpression();
                        rootExpression.Elements.Add(andExpression);
                    }
                    else // multiple where clauses are joined by AND
                    {
                        andExpression = rootExpression.Elements[0];
                    }


                    var leaf = new LeafExpression();
                    andExpression.Elements.Add(leaf);

                    VisitContainsExpression(subQuery, leaf);
                }
            }
            else if (binaryExpression.Left.NodeType == ExpressionType.OrElse)
            {
                VisitOrExpression((BinaryExpression)binaryExpression.Left, rootExpression);
            }
            else if (binaryExpression.Left.NodeType == ExpressionType.AndAlso)
            {
                var andExpression = new ExplainAndExpression();
                rootExpression.Elements.Add(andExpression);
                VisitAndExpression((BinaryExpression)binaryExpression.Left, andExpression);
            }
            else if (binaryExpression.Left is MethodCallExpression call)
            {
                ExplainAndExpression andExpression;

                if (!RootExpression.MultipleWhereClauses)
                {
                    andExpression = new ExplainAndExpression();
                    RootExpression.Elements.Add(andExpression);
                }
                else // multiple where clauses are joined by AND
                {
                    andExpression = RootExpression.Elements[0];
                }

                var leaf = CallToLeafExpression(call);
                andExpression.Elements.Add(leaf);
            }
            else
            {
                throw new NotSupportedException("ExplainExpression too complex");
            }

            // visit right part
            if (IsLeafExpression(binaryExpression.Right))
            {
                var andExpression = new ExplainAndExpression();
                rootExpression.Elements.Add(andExpression);

                andExpression.Elements.Add(VisitLeafExpression((BinaryExpression)binaryExpression.Right));
            }
            else if (binaryExpression.Right.NodeType == ExpressionType.Extension)
            {
                if (binaryExpression.Right is SubQueryExpression subQuery)
                {
                    var andExpression = new ExplainAndExpression();
                    rootExpression.Elements.Add(andExpression);

                    if (rootExpression.MultipleWhereClauses)
                    {
                        throw new NotSupportedException(
                                  "Multiple where clauses can be used only with simple expressions");
                    }


                    var leaf = new LeafExpression();
                    andExpression.Elements.Add(leaf);
                    VisitContainsExpression(subQuery, leaf);
                }
            }
            else if (binaryExpression.Right.NodeType == ExpressionType.OrElse)
            {
                VisitOrExpression((BinaryExpression)binaryExpression.Right, rootExpression);
            }
            else if (binaryExpression.Right.NodeType == ExpressionType.AndAlso)
            {
                var andExpression = new ExplainAndExpression();
                rootExpression.Elements.Add(andExpression);
                VisitAndExpression((BinaryExpression)binaryExpression.Right, andExpression);
            }
            else if (binaryExpression.Right is MethodCallExpression call)
            {
                ExplainAndExpression andExpression;

                if (!RootExpression.MultipleWhereClauses)
                {
                    andExpression = new ExplainAndExpression();
                    RootExpression.Elements.Add(andExpression);
                }
                else // multiple where clauses are joined by AND
                {
                    andExpression = RootExpression.Elements[0];
                }

                var leaf = CallToLeafExpression(call);
                andExpression.Elements.Add(leaf);
            }
            else
            {
                throw new NotSupportedException("ExplainExpression too complex");
            }
        }