Beispiel #1
0
        public void WhereEqual(MemberExpression expression, ConstantExpression c)
        {
            if (c.Value == null)
            {
                // If we want to filter for non-bound values we need to mark the properties as optional.
                SparqlVariable so = BuildMemberAccessOptional(expression);

                // TODO: If we filter a resource, make sure it has been described with variables in the local scope.

                // Comparing with null means the variable is not bound.
                PatternBuilder.Filter(e => !e.Bound(so.Name));
            }
            else if (c.Type.IsValueType || c.Type == typeof(string))
            {
                if (expression.Member.DeclaringType == typeof(string))
                {
                    BuildMemberAccess(expression);

                    // If we are comparing a property of string we need to implement SPARQL built-in call on the variable such as STRLEN..
                    BuildBuiltInCall(expression, e => e == c.AsNumericExpression());
                }
                else
                {
                    // TODO: The default value for a property may be overridden with the DefaultValue attribute.
                    object defaultValue = TypeHelper.GetDefaultValue(c.Type);

                    // If the value IS the default value, WhereEquals includes the default value and therefore includes non-bound values..
                    if (c.Value.Equals(defaultValue))
                    {
                        // If we want to filter for non-bound values we need to mark the properties as optional.
                        SparqlVariable o = BuildMemberAccessOptional(expression);

                        // Mark the variable to be coalesced with the default value when selected.
                        CoalescedVariables[o] = Expression.Constant(defaultValue).AsLiteralExpression();

                        // Comparing with null means the variable is not bound.
                        PatternBuilder.Filter(e => e.Variable(o.Name) == c.AsLiteralExpression() || !e.Bound(o.Name));
                    }
                    else
                    {
                        // If we want to filter bound literal values, we still write them into a variable so they can be selected.
                        SparqlVariable o = BuildMemberAccess(expression);

                        PatternBuilder.Filter(e => e.Variable(o.Name) == c.AsLiteralExpression());
                    }
                }
            }
            else
            {
                // We are comparing reference types / resources against a bound value here.
                SparqlVariable so = BuildMemberAccess(expression);

                // TODO: If we filter a resource, make sure it has been described with variables in the local scope.

                PatternBuilder.Filter(e => e.Variable(so.Name) == c.AsIriExpression());
            }
        }
Beispiel #2
0
 public void WhereNotEqual(SparqlVariable v, ConstantExpression c)
 {
     if (c.Value == null)
     {
         PatternBuilder.Filter(e => e.Bound(v.Name));
     }
     else if (c.Type.IsValueType || c.Type == typeof(string))
     {
         PatternBuilder.Filter(e => e.Variable(v.Name) != c.AsLiteralExpression());
     }
     else
     {
         PatternBuilder.Filter(e => e.Variable(v.Name) != c.AsIriExpression());
     }
 }
Beispiel #3
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);
                }
            }
        }