예제 #1
0
        public override void OnSelectClauseVisited(Expression selector)
        {
            if (QueryModel.HasResultOperator <SkipResultOperator>() ||
                QueryModel.HasResultOperator <TakeResultOperator>() ||
                QueryModel.HasResultOperator <FirstResultOperator>() ||
                QueryModel.HasResultOperator <LastResultOperator>())
            {
                // Finally, if we have a SKIP or TAKE operator on the root query, set the current
                // query generator as a child.
                ISparqlQueryGenerator subGenerator = QueryGeneratorTree.GetQueryGenerator(selector);

                Child(subGenerator);
            }
        }
예제 #2
0
        private void GenerateTypeConstraintOnSubject(ISparqlQueryGenerator generator, Expression selector)
        {
            Type type = null;

            if (selector is ConstantExpression)
            {
                type = (selector as ConstantExpression).Value.GetType();
            }
            else if (selector is MemberExpression)
            {
                type = (selector as MemberExpression).Member.GetMemberType();
            }
            else if (selector is QuerySourceReferenceExpression)
            {
                type = (selector as QuerySourceReferenceExpression).ReferencedQuerySource.ItemType;
            }

            if (type != null && type.IsSubclassOf(typeof(Resource)))
            {
                generator.WhereResourceOfType(VariableGenerator.GlobalSubject, type);
            }
        }
예제 #3
0
 public SubSelectQueryGenerator(ISparqlQueryGenerator parent)
 {
     IsRoot            = false;
     VariableGenerator = new SparqlVariableGenerator(parent.VariableGenerator);
 }
예제 #4
0
        public override void OnBeforeSelectClauseVisited(Expression selector)
        {
            base.OnBeforeSelectClauseVisited(selector);

            Type selectedType = TryGetSelectedType(selector);

            if (selectedType == null || !typeof(Resource).IsAssignableFrom(selectedType))
            {
                throw new NotSupportedException(selectedType.ToString());
            }

            // 1. We always create an outer query which selects all triples that describe our resources.
            SparqlVariable s_ = VariableGenerator.GlobalSubject;
            SparqlVariable p_ = VariableGenerator.GlobalPredicate;
            SparqlVariable o_ = VariableGenerator.GlobalObject;

            VariableGenerator.SetSubjectVariable(selector, s_);
            VariableGenerator.SetPredicateVariable(selector, p_);
            VariableGenerator.SetObjectVariable(selector, o_);

            SetSubjectVariable(s_);
            SetObjectVariable(o_);

            SelectVariable(s_);
            SelectVariable(p_);
            SelectVariable(o_);

            WhereResource(s_, p_, o_);

            // If we are describing resources using a SKIP or TAKE operator, we need to make sure that
            // these operations are on a per-resource basis and all triples for the described resources
            // are contained in the result.
            if (QueryModel.HasResultOperator <SkipResultOperator>() ||
                QueryModel.HasResultOperator <TakeResultOperator>() ||
                QueryModel.HasResultOperator <FirstResultOperator>() ||
                QueryModel.HasResultOperator <LastResultOperator>())
            {
                // ..which are described in an inner query on which the LIMIT and OFFSET operators are set.
                // This results in a SELECT query that acts like a DESCRIBE but ist faster on most triple
                // stores as the triples can be returend via bindings and must not be parsed.
                ISparqlQueryGenerator subGenerator = QueryGeneratorTree.CreateSubQueryGenerator(this, selector);

                subGenerator.SetSubjectVariable(s_, true);
                subGenerator.SetObjectVariable(o_);

                GenerateTypeConstraintOnSubject(subGenerator, selector);

                QueryGeneratorTree.CurrentGenerator = subGenerator;

                // NOTE: We set the subGenerator as a child *AFTER* the select clause and body clauses
                // have been processed (see <c>OnSelectClauseVisited</c>). This is because the dotNetRDF
                // query generator does not correctly handle result operators when it is already set as a child.
            }
            else if (!QueryModel.HasTypeConstraintOnExpression(selector))
            {
                // NOTE: This should not be done here. Simply because the HasTypeConstraintOnExpression
                // requires us to look ahead at the body clauses which is already done in more detail
                // by the expression visitor. We need a way to generate the type constraint after the query
                // has been visited and no type constraint was generated.
                GenerateTypeConstraintOnSubject(this, selector);
            }

            if (selector is MemberExpression)
            {
                MemberExpression memberExpression = selector as MemberExpression;

                BuildMemberAccess(memberExpression);
            }
        }