private SparqlGeneratorWhereExpressionTreeVisitor(SparqlQueryBuilder queryBuilder, bool optimizeFilter, bool isBoolean)
     : base(queryBuilder)
 {
     QueryBuilder         = queryBuilder;
     _filterWriter        = new FilterWriter(this, queryBuilder, new StringBuilder());
     _optimizeFilter      = optimizeFilter;
     _inBooleanExpression = isBoolean;
 }
示例#2
0
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is ContainsResultOperator)
            {
                var contains = expression.QueryModel.ResultOperators[0] as ContainsResultOperator;
                if (expression.QueryModel.MainFromClause.FromExpression.NodeType == ExpressionType.Constant &&
                    contains.Item is MemberExpression)
                {
                    var itemExpression = VisitExpression(contains.Item);
                    if (itemExpression is SelectVariableNameExpression)
                    {
                        // We can translate the subquery to an IN expression
                        _filterWriter.WriteInFilter(contains.Item, expression.QueryModel.MainFromClause.FromExpression);
                        return(expression);
                    }
                }
                else if (expression.QueryModel.MainFromClause.FromExpression.NodeType == ExpressionType.MemberAccess)
                {
                    var itemExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                    if (itemExpression is SelectVariableNameExpression)
                    {
                        _filterWriter.WriteInFilter(expression.QueryModel.MainFromClause.FromExpression,
                                                    contains.Item);
                        return(expression);
                    }
                }
            }
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is AllResultOperator)
            {
                var all = expression.QueryModel.ResultOperators[0] as AllResultOperator;
                if (all != null)
                {
                    FilterWriter existingWriter = _filterWriter;
                    _filterWriter = new FilterWriter(this, this.QueryBuilder, new StringBuilder());
                    QueryBuilder.StartNotExists();
                    var mappedExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                    QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedExpression);
                    _filterWriter.WriteInvertedFilterPredicate(all.Predicate);
                    QueryBuilder.AddFilterExpression(_filterWriter.FilterExpression);
                    QueryBuilder.EndNotExists();
                    _filterWriter = existingWriter;
                    return(expression);
                }
            }
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is AnyResultOperator)
            {
                QueryBuilder.StartExists();
                var outerFilterWriter = _filterWriter;
                _filterWriter = new FilterWriter(this, QueryBuilder, new StringBuilder());
                var itemVarName = SparqlQueryBuilder.SafeSparqlVarName(expression.QueryModel.MainFromClause.ItemName);

                var mappedFromExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedFromExpression);
                if (mappedFromExpression is SelectVariableNameExpression)
                {
                    QueryBuilder.RenameVariable((mappedFromExpression as SelectVariableNameExpression).Name,
                                                itemVarName);
                }

                foreach (var bodyClause in expression.QueryModel.BodyClauses)
                {
                    if (bodyClause is WhereClause)
                    {
                        var whereClause = bodyClause as WhereClause;
                        VisitExpression(whereClause.Predicate);
                    }
                    else
                    {
                        CreateUnhandledItemException(bodyClause, "VisitSubQueryExpression");
                    }
                }
                var innerFilter = _filterWriter.ToString();
                if (!String.IsNullOrEmpty(innerFilter))
                {
                    QueryBuilder.AddFilterExpression(innerFilter);
                }
                _filterWriter = outerFilterWriter;
                QueryBuilder.EndExists();
                return(expression);
            }
            else if (expression.QueryModel.ResultOperators.Count == 0)
            {
                var itemVarName          = SparqlQueryBuilder.SafeSparqlVarName(expression.QueryModel.MainFromClause.ItemName);
                var mappedFromExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedFromExpression);
                if (mappedFromExpression is SelectVariableNameExpression)
                {
                    // Rename the variable in the SPARQL so that it matches the LINQ variable
                    QueryBuilder.RenameVariable((mappedFromExpression as SelectVariableNameExpression).Name, itemVarName);
                    (mappedFromExpression as SelectVariableNameExpression).Name = itemVarName;
                }
                foreach (var bodyClause in expression.QueryModel.BodyClauses)
                {
                    if (bodyClause is WhereClause)
                    {
                        var whereClause = bodyClause as WhereClause;
                        VisitExpression(whereClause.Predicate);
                    }
                    else
                    {
                        CreateUnhandledItemException(bodyClause, "VisitSubQueryExpression");
                    }
                }
                return(mappedFromExpression);
            }
            return(base.VisitSubQueryExpression(expression));
        }
示例#3
0
 private SparqlGeneratorWhereExpressionTreeVisitor(SparqlQueryBuilder queryBuilder) : base(queryBuilder)
 {
     QueryBuilder  = queryBuilder;
     _filterWriter = new FilterWriter(this, queryBuilder, new StringBuilder());
 }
        protected override Expression VisitSubQueryExpression(SubQueryExpression expression)
        {
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is ContainsResultOperator)
            {
                var contains = (ContainsResultOperator)expression.QueryModel.ResultOperators[0];
                if (expression.QueryModel.MainFromClause.FromExpression.NodeType == ExpressionType.Constant &&
                    contains.Item is MemberExpression)
                {
                    var memberExpression  = (MemberExpression)contains.Item;
                    var itemExpression    = VisitExpression(contains.Item);
                    var varNameExpression = itemExpression as SelectVariableNameExpression;
                    if (varNameExpression != null)
                    {
                        if (IsIdInArraySubQuery(memberExpression, expression.QueryModel.MainFromClause.FromExpression))
                        {
                            var varName = varNameExpression.Name;
                            // The subquery is a filter on a resource IRI
                            // It is more efficient to use a UNION of BIND triple patterns than a FILTER
                            var values =
                                ((ConstantExpression)expression.QueryModel.MainFromClause.FromExpression).Value as
                                IEnumerable;
                            if (values != null)
                            {
                                var identifierProperty = memberExpression.Member as PropertyInfo;
                                QueryBuilder.StartUnion();
                                foreach (var value in values)
                                {
                                    QueryBuilder.StartUnionElement();
                                    QueryBuilder.AddBindExpression(
                                        "<" + QueryBuilder.Context.MapIdToUri(identifierProperty, value.ToString()) +
                                        ">", varName);
                                    QueryBuilder.EndUnionElement();
                                }
                                QueryBuilder.EndUnion();
                                return(expression);
                            }
                            return(base.VisitSubQueryExpression(expression));
                        }
                        else
                        {
                            // The subquery is a filter on a resource property expression
                            // We can translate the subquery to an IN expression
                            _filterWriter.WriteInFilter(itemExpression,
                                                        expression.QueryModel.MainFromClause.FromExpression);
                            return(expression);
                        }
                    }
                }
                else if (expression.QueryModel.MainFromClause.FromExpression.NodeType == ExpressionType.MemberAccess)
                {
                    var itemExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                    if (itemExpression is SelectVariableNameExpression)
                    {
                        _filterWriter.WriteInFilter(expression.QueryModel.MainFromClause.FromExpression,
                                                    contains.Item);
                        return(expression);
                    }
                }
            }
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is AllResultOperator)
            {
                var all            = (AllResultOperator)expression.QueryModel.ResultOperators[0];
                var existingWriter = _filterWriter;
                _filterWriter = new FilterWriter(this, QueryBuilder, new StringBuilder()); // TODO: Could check FromExpression to see if it is optimisable
                QueryBuilder.StartNotExists();
                var mappedExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedExpression);
                _filterWriter.WriteInvertedFilterPredicate(all.Predicate);
                QueryBuilder.AddFilterExpression(_filterWriter.FilterExpression);
                QueryBuilder.EndNotExists();
                _filterWriter = existingWriter;
                return(expression);
            }
            if (expression.QueryModel.ResultOperators.Count == 1 &&
                expression.QueryModel.ResultOperators[0] is AnyResultOperator)
            {
                QueryBuilder.StartExists();
                var outerFilterWriter = _filterWriter;
                _filterWriter = new FilterWriter(this, QueryBuilder, new StringBuilder());
                var itemVarName = SparqlQueryBuilder.SafeSparqlVarName(expression.QueryModel.MainFromClause.ItemName);

                var mappedFromExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedFromExpression);
                if (mappedFromExpression is SelectVariableNameExpression)
                {
                    QueryBuilder.RenameVariable((mappedFromExpression as SelectVariableNameExpression).Name,
                                                itemVarName);
                }

                foreach (var bodyClause in expression.QueryModel.BodyClauses)
                {
                    if (bodyClause is WhereClause)
                    {
                        var whereClause = bodyClause as WhereClause;
                        VisitExpression(whereClause.Predicate);
                    }
                    else
                    {
                        CreateUnhandledItemException(bodyClause, "VisitSubQueryExpression");
                    }
                }
                var innerFilter = _filterWriter.ToString();
                if (!string.IsNullOrEmpty(innerFilter))
                {
                    QueryBuilder.AddFilterExpression(innerFilter);
                }
                _filterWriter = outerFilterWriter;
                QueryBuilder.EndExists();
                return(expression);
            }
            else if (expression.QueryModel.ResultOperators.Count == 0)
            {
                var itemVarName          = SparqlQueryBuilder.SafeSparqlVarName(expression.QueryModel.MainFromClause.ItemName);
                var mappedFromExpression = VisitExpression(expression.QueryModel.MainFromClause.FromExpression);
                QueryBuilder.AddQuerySourceMapping(expression.QueryModel.MainFromClause, mappedFromExpression);
                if (mappedFromExpression is SelectVariableNameExpression)
                {
                    // Rename the variable in the SPARQL so that it matches the LINQ variable
                    QueryBuilder.RenameVariable((mappedFromExpression as SelectVariableNameExpression).Name, itemVarName);
                    (mappedFromExpression as SelectVariableNameExpression).Name = itemVarName;
                }
                foreach (var bodyClause in expression.QueryModel.BodyClauses)
                {
                    if (bodyClause is WhereClause)
                    {
                        var whereClause = bodyClause as WhereClause;
                        VisitExpression(whereClause.Predicate);
                    }
                    else
                    {
                        CreateUnhandledItemException(bodyClause, "VisitSubQueryExpression");
                    }
                }
                return(mappedFromExpression);
            }
            return(base.VisitSubQueryExpression(expression));
        }