Пример #1
0
        public void WriteInFilter(Expression itemExpression, Expression fromExpression)
        {
            _filterExpressionBuilder.Append("(");
            var expr = VisitExpression(itemExpression);

            if (expr is SelectVariableNameExpression &&
                ((expr) as SelectVariableNameExpression).BindingType == VariableBindingType.Resource)
            {
                _castAsResourceType = true;
                _identifierPrefix   = EntityMappingStore.GetIdentifierPrefix(expr.Type);
                //_identifierPrefix = EntityMappingStore.GetIdentifierPrefix(((SelectVariableNameExpression)expr).
            }
            _filterExpressionBuilder.Append(" IN (");
            VisitExpression(fromExpression);
            _filterExpressionBuilder.Append("))");
            _castAsResourceType = false;
        }
Пример #2
0
        /// <summary>
        /// Convert a "Compare" expression into a SPARQL greater than / less than
        /// </summary>
        /// <param name="compareExpression"></param>
        /// <param name="nodeType"></param>
        /// <remarks>The Compare expression is used by Microsoft WCF Data Services when a OData call is made with a $skiptoken query option. This token is used to find the starting point in a collection of entities</remarks>
        private void HandleCompareExpression(MethodCallExpression compareExpression, ExpressionType nodeType)
        {
            var filter = nodeType == ExpressionType.GreaterThan
                                  ? "(?{0} > '{1}')"
                                  : "(?{0} < '{1}')";
            var expression         = compareExpression.Arguments[0] as MemberExpression;
            var sourceVarName      = GetSourceVarName(expression);
            var constantExpression = compareExpression.Arguments[1] as ConstantExpression;
            var value = constantExpression.Value.ToString();

            if (sourceVarName != null)
            {
#if PORTABLE
                if (expression.Member is PropertyInfo)
#else
                if (expression.Member.MemberType == MemberTypes.Property)
#endif
                {
                    var propertyInfo = expression.Member as PropertyInfo;
                    var hint         = QueryBuilder.Context.GetPropertyHint(propertyInfo);

                    if (hint != null)
                    {
                        switch (hint.MappingType)
                        {
                        case PropertyMappingType.Id:
                            filter = nodeType == ExpressionType.GreaterThan
                                  ? "(str(?{0}) > '{1}')"
                                  : "(str(?{0}) < '{1}')";
                            var prefix = EntityMappingStore.GetIdentifierPrefix(propertyInfo.DeclaringType);
                            _filterWriter.AppendFormat(filter, sourceVarName, prefix + value);
                            break;

                        case PropertyMappingType.Arc:
                        case PropertyMappingType.Property:
                        {
                            var existingVarName = QueryBuilder.GetVariableForObject(GraphNode.Variable,
                                                                                    sourceVarName,
                                                                                    GraphNode.Iri,
                                                                                    hint.SchemaTypeUri);
                            if (!String.IsNullOrEmpty(existingVarName))
                            {
                                _filterWriter.AppendFormat(filter, existingVarName, value);
                            }
                            else
                            {
                                var varName = QueryBuilder.NextVariable();
                                QueryBuilder.AddTripleConstraint(
                                    GraphNode.Variable, sourceVarName,
                                    GraphNode.Iri, hint.SchemaTypeUri,
                                    GraphNode.Variable, varName);
                                _filterWriter.AppendFormat(filter, varName, value);
                            }
                            break;
                        }

                        case PropertyMappingType.InverseArc:
                        {
                            var existingVarName = QueryBuilder.GetVariableForSubject(GraphNode.Iri,
                                                                                     hint.SchemaTypeUri,
                                                                                     GraphNode.Variable,
                                                                                     sourceVarName);
                            if (!String.IsNullOrEmpty(existingVarName))
                            {
                                _filterWriter.AppendFormat(filter, existingVarName, value);
                            }
                            else
                            {
                                var varName = QueryBuilder.NextVariable();
                                QueryBuilder.AddTripleConstraint(GraphNode.Variable, varName,
                                                                 GraphNode.Iri, hint.SchemaTypeUri,
                                                                 GraphNode.Variable, sourceVarName);
                                _filterWriter.AppendFormat(filter, varName, value);
                            }
                        }
                        break;

                        case PropertyMappingType.Address:
                            _filterWriter.AppendFormat(filter, sourceVarName, value);
                            break;
                        }
                    }
                }
            }
        }
        protected override Expression VisitMemberExpression(MemberExpression expression)
        {
            string sourceVarName = null;

            if (expression.Expression is QuerySourceReferenceExpression)
            {
                var        source = expression.Expression as QuerySourceReferenceExpression;
                Expression mappedSourceExpression;
                sourceVarName = source.ReferencedQuerySource.ItemName;
                if (_queryBuilder.TryGetQuerySourceMapping(source.ReferencedQuerySource, out mappedSourceExpression) && mappedSourceExpression is SelectVariableNameExpression)
                {
                    sourceVarName = (mappedSourceExpression as SelectVariableNameExpression).Name;
                }
            }
            else if (expression.Expression is MemberExpression)
            {
                var memberExpression = VisitExpression(expression.Expression);
                if (memberExpression is SelectVariableNameExpression)
                {
                    sourceVarName = (memberExpression as SelectVariableNameExpression).Name;
                }
            }
            else if (expression.Expression is UnaryExpression)
            {
                var unary = expression.Expression as UnaryExpression;
                if (unary.NodeType == ExpressionType.TypeAs &&
                    unary.Operand is QuerySourceReferenceExpression)
                {
                    var targetType = unary.Type;
                    var source     = unary.Operand as QuerySourceReferenceExpression;
                    if (source != null)
                    {
                        var itemType = source.ReferencedQuerySource.ItemType;
                        if (targetType.IsAssignableFrom(itemType))
                        {
                            expression = Expression.MakeMemberAccess(unary.Operand, expression.Member);
                            return(VisitExpression(expression));
                        }
                    }
                }
                var updatedExpression = VisitExpression(expression.Expression) as UnaryExpression;
                if (updatedExpression != null && updatedExpression.Operand is SelectVariableNameExpression)
                {
#if WINDOWS_PHONE || PORTABLE
                    return(Expression.MakeMemberAccess(updatedExpression, expression.Member));
#else
                    return(expression.Update(updatedExpression));
#endif
                }
            }
            if (!String.IsNullOrEmpty(sourceVarName))
            {
#if PORTABLE
                if (expression.Member is PropertyInfo)
#else
                if (expression.Member.MemberType == MemberTypes.Property)
#endif
                {
                    var propertyInfo = expression.Member as PropertyInfo;
                    var propertyHint = _queryBuilder.Context.GetPropertyHint(propertyInfo);
                    if (propertyHint != null)
                    {
                        switch (propertyHint.MappingType)
                        {
                        case PropertyMappingType.Arc:
                        {
                            var memberVarName = _queryBuilder.GetVariableForObject(
                                GraphNode.Variable, sourceVarName,
                                GraphNode.Iri, propertyHint.SchemaTypeUri);
                            if (memberVarName == null)
                            {
                                memberVarName = _queryBuilder.NextVariable();
                                _queryBuilder.AddTripleConstraint(
                                    GraphNode.Variable, sourceVarName,
                                    GraphNode.Iri, propertyHint.SchemaTypeUri,
                                    GraphNode.Variable, memberVarName);
                            }
                            return(new SelectVariableNameExpression(memberVarName, VariableBindingType.Resource, propertyInfo.PropertyType));
                        }

                        case PropertyMappingType.InverseArc:
                        {
                            var memberVarName = _queryBuilder.GetVariableForSubject(
                                GraphNode.Iri, propertyHint.SchemaTypeUri,
                                GraphNode.Variable, sourceVarName);
                            if (memberVarName == null)
                            {
                                memberVarName = _queryBuilder.NextVariable();
                                _queryBuilder.AddTripleConstraint(
                                    GraphNode.Variable, memberVarName,
                                    GraphNode.Iri, propertyHint.SchemaTypeUri,
                                    GraphNode.Variable, sourceVarName);
                            }
                            return(new SelectVariableNameExpression(memberVarName, VariableBindingType.Resource, propertyInfo.PropertyType));
                        }

                        case PropertyMappingType.Property:
                        {
                            var propertyValueVarName = _queryBuilder.GetVariableForObject(GraphNode.Variable,
                                                                                          sourceVarName,
                                                                                          GraphNode.Iri,
                                                                                          propertyHint.
                                                                                          SchemaTypeUri);
                            if (propertyValueVarName == null)
                            {
                                propertyValueVarName = _queryBuilder.NextVariable();
                                _queryBuilder.AddTripleConstraint(
                                    GraphNode.Variable, sourceVarName,
                                    GraphNode.Iri, propertyHint.SchemaTypeUri,
                                    GraphNode.Variable, propertyValueVarName);
                            }
                            return(new SelectVariableNameExpression(propertyValueVarName,
                                                                    VariableBindingType.Literal, propertyInfo.PropertyType));
                        }

                        case PropertyMappingType.Address:
                        {
                            return(new SelectVariableNameExpression(sourceVarName, VariableBindingType.Resource, propertyInfo.PropertyType));
                        }

                        case PropertyMappingType.Id:
                        {
                            var prefix = EntityMappingStore.GetIdentifierPrefix(propertyInfo.DeclaringType);
                            return(new SelectIdentifierVariableNameExpression(sourceVarName, prefix));
                            //return new SelectVariableNameExpression(sourceVarName, VariableBindingType.Resource, propertyInfo.PropertyType);
                        }
                        }
                    }
                }
            }
            return(base.VisitMemberExpression(expression));
        }