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); } }
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); } }
public SubSelectQueryGenerator(ISparqlQueryGenerator parent) { IsRoot = false; VariableGenerator = new SparqlVariableGenerator(parent.VariableGenerator); }
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); } }