예제 #1
0
        public void FilterNotRegex(MemberExpression expression, string pattern, bool ignoreCase)
        {
            SparqlVariable s = VariableGenerator.TryGetSubjectVariable(expression) ?? SubjectVariable;
            SparqlVariable o = VariableGenerator.TryGetObjectVariable(expression) ?? VariableGenerator.CreateObjectVariable(expression);

            BuildMemberAccess(expression);

            FilterNotRegex(o, pattern, ignoreCase);
        }
예제 #2
0
        public override void OnBeforeFromClauseVisited(Expression expression)
        {
            SparqlVariable s = null;
            SparqlVariable o = null;

            if (expression is MemberExpression)
            {
                QuerySourceReferenceExpression sourceExpression = expression.TryGetQuerySourceReference();

                s = VariableGenerator.TryGetSubjectVariable(sourceExpression) ?? VariableGenerator.TryGetObjectVariable(sourceExpression);
                o = VariableGenerator.CreateObjectVariable(expression);

                // The from clause is parsed first when handling a query. This allows us to detect if the
                // query source is a subquery and proceed with implementing it _before_ hanlding its results.
                MemberExpression memberExpression = expression as MemberExpression;

                if (s.IsGlobal())
                {
                    Type type = memberExpression.Member.DeclaringType;

                    if (type.IsSubclassOf(typeof(Resource)))
                    {
                        WhereResourceOfType(s, type);
                    }
                }

                // If the query model has a numeric result operator, we make all the following
                // expressions optional in order to also allow to count zero occurences.
                if (QueryModel.HasNumericResultOperator())
                {
                    GraphPatternBuilder optionalBuilder = new GraphPatternBuilder(GraphPatternType.Optional);

                    Child(optionalBuilder);

                    PatternBuilder = optionalBuilder;
                }
            }
            else
            {
                s = VariableGenerator.TryGetSubjectVariable(expression);
                o = VariableGenerator.TryGetObjectVariable(expression);
            }

            if (s != null && o != null)
            {
                // Set the variable name of the query source reference as subject of the current query.
                SetSubjectVariable(s, true);
                SetObjectVariable(o, true);
            }
        }
예제 #3
0
        public void WhereResourceNotOfType(Expression expression, Type type)
        {
            SparqlVariable so = VariableGenerator.TryGetSubjectVariable(expression) ?? VariableGenerator.TryGetObjectVariable(expression);

            WhereResourceNotOfType(so, type);
        }
예제 #4
0
        public void WhereResource(Expression expression, SparqlVariable p, SparqlVariable o)
        {
            SparqlVariable s = VariableGenerator.TryGetSubjectVariable(expression) ?? SubjectVariable;

            PatternBuilder.Where(t => t.Subject(s).Predicate(p).Object(o));
        }
예제 #5
0
        private SparqlVariable BuildMemberAccess(MemberExpression memberExpression, IGraphPatternBuilder patternBuilder)
        {
            MemberInfo member = memberExpression.Member;

            // If we do access a member of a system type, like string.Length we actually select the
            // the declaring member and invoke a SPARQL built in call to get the value.
            if (member.IsBuiltInCall())
            {
                MemberExpression parentMember = memberExpression.Expression as MemberExpression;

                return(BuildMemberAccess(parentMember, patternBuilder));
            }
            else if (memberExpression.Expression is MemberExpression)
            {
                MemberExpression parentMember = memberExpression.Expression as MemberExpression;

                // Note: When we build an optional property path, we consider the relation to the
                // parent properties of the accessed property to be non-optional.
                IGraphPatternBuilder builder = member.IsUriType() ? patternBuilder : PatternBuilder;

                // We might encounter property paths (i.e. contact.Organization.Name). Therefore,
                // implement the parent expression of the current member recursively..
                SparqlVariable po = BuildMemberAccess(parentMember, builder);

                // If we are building a node on a property path (parentExpression != null), we associate
                // the object variable with the parent expression so that it becomes the subject of the parent.
                VariableGenerator.SetSubjectVariable(memberExpression, po);
            }

            if (member.IsUriType())
            {
                // When we access the .Uri member of a resource we do not need a property mapping and return the subject as the bound variable.

                // We create a triple pattern describing the resource in the local scope just in case it has not been described yet.
                // Todo: Improve. Check if triples actually need to be asserted.
                SparqlVariable s = VariableGenerator.TryGetSubjectVariable(memberExpression) ?? SubjectVariable;
                SparqlVariable p = VariableGenerator.CreatePredicateVariable();
                SparqlVariable o = VariableGenerator.CreateObjectVariable(memberExpression);

                patternBuilder.Where(t => t.Subject(s).Predicate(p).Object(o));

                VariableGenerator.SetSubjectVariable(memberExpression, s);

                return(s);
            }
            else if (memberExpression.Expression is QuerySourceReferenceExpression)
            {
                QuerySourceReferenceExpression querySource = memberExpression.Expression as QuerySourceReferenceExpression;

                if (VariableGenerator.TryGetSubjectVariable(memberExpression) == VariableGenerator.GlobalSubject)
                {
                    // In case the accessed member is the global query subject (i.e. from x select x.Y)..
                    SparqlVariable s = VariableGenerator.TryGetSubjectVariable(querySource);
                    SparqlVariable o = VariableGenerator.GlobalSubject;

                    if (s == null)
                    {
                        s = VariableGenerator.CreateSubjectVariable(querySource);

                        BuildMemberAccess(memberExpression, patternBuilder, member, s, o);
                    }

                    return(o);
                }
                else
                {
                    // Otherwise we are accessing a member of the globale query subject (i.e. from x where x.Y select x)
                    SparqlVariable s = VariableGenerator.TryGetSubjectVariable(querySource) ?? VariableGenerator.GlobalSubject;
                    SparqlVariable o = VariableGenerator.TryGetObjectVariable(memberExpression) ?? VariableGenerator.CreateObjectVariable(memberExpression);

                    BuildMemberAccess(memberExpression, patternBuilder, member, s, o);

                    return(o);
                }
            }
            else
            {
                SparqlVariable s = VariableGenerator.TryGetSubjectVariable(memberExpression) ?? VariableGenerator.CreateSubjectVariable(memberExpression);
                SparqlVariable o = VariableGenerator.TryGetObjectVariable(memberExpression) ?? VariableGenerator.CreateObjectVariable(memberExpression);

                BuildMemberAccess(memberExpression, patternBuilder, member, s, o);

                return(o);
            }
        }
예제 #6
0
        public override void OnBeforeSelectClauseVisited(Expression selector)
        {
            base.OnBeforeSelectClauseVisited(selector);

            QuerySourceReferenceExpression sourceExpression = selector.TryGetQuerySourceReference();

            if (sourceExpression != null)
            {
                // Register the query source with the global variable for sub-queries.
                SparqlVariable s = VariableGenerator.TryGetSubjectVariable(sourceExpression) ?? VariableGenerator.GlobalSubject;

                // Assert the object type.
                if (sourceExpression.Type.IsSubclassOf(typeof(Resource)))
                {
                    WhereResourceOfType(s, sourceExpression.Type);
                }

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

                    SparqlVariable o = VariableGenerator.CreateObjectVariable(memberExpression);

                    // Select all triples having the resource as subject.
                    SetSubjectVariable(s);
                    SetObjectVariable(o, true);

                    // If the member expression is not selected in the WHERE block, we add it here.
                    // Scenarios:
                    // - from x in Model.AsQueryable<X>() select x.B
                    // - from x in Model.AsQueryable<X>() where x.A select x.B
                    string e = memberExpression.ToString();

                    if (!QueryModel.BodyClauses.OfType <WhereClause>().Any(c => c.Predicate.ToString().Contains(e)))
                    {
                        // We select the member without a constraint on its value.
                        QueryModel.BodyClauses.Add(new WhereClause(memberExpression));

                        // Since there is no constraint on the member, we also need to select the ones that are not bound.
                        Type memberType = memberExpression.Member.GetMemberType();

                        // TODO: There might be a different default value on the member using the DefaultValue() attribute.
                        object defaultValue = TypeHelper.GetDefaultValue(memberType);

                        if (defaultValue != null && memberType != typeof(string))
                        {
                            ConstantExpression coalescedValue = Expression.Constant(defaultValue);

                            // Mark the variable to be coalesced with the default value when selected.
                            CoalescedVariables[o] = coalescedValue.AsLiteralExpression();
                        }
                    }
                }
                else if (QueryModel.HasNumericResultOperator())
                {
                    // If we have a numeric result operator on the root query, make the
                    // subject variable known so that the model visitor can handle it.
                    SetSubjectVariable(s);
                }
            }
        }