internal void OverrideTarget(ResourceSetExpression newTarget)
        {
            Debug.Assert(newTarget != null, "Resource set cannot be null");
            Debug.Assert(newTarget.ResourceType.Equals(this.Type), "Cannot reference a resource set with a different resource type");

            this.target = newTarget;
        }
        internal virtual Expression VisitResourceSetExpression(ResourceSetExpression rse)
        {
            Expression source = this.Visit(rse.Source);

            if (source != rse.Source)
            {
                rse = new ResourceSetExpression(rse.Type, source, rse.MemberExpression, rse.ResourceType, rse.ExpandPaths, rse.CountOption, rse.CustomQueryOptions, rse.Projection);
            }

            return(rse);
        }
예제 #3
0
 internal override Expression VisitResourceSetExpression(ResourceSetExpression rse)
 {
     /* if ((ResourceExpressionType)rse.NodeType == ResourceExpressionType.ResourceNavigationProperty)
      * {
      *  this.Visit(rse.Source);
      *  this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(this.ExpressionToString(rse.MemberExpression));
      * }
      * else
      * {
      *  this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append((string)((ConstantExpression)rse.MemberExpression).Value);
      * }
      *
      * TODO optimize for point query
      * if (rse.KeyPredicate != null)
      * {
      *  this.uriBuilder.Append(UriHelper.LEFTPAREN);
      *  if (rse.KeyPredicate.Count == 1)
      *  {
      *      this.uriBuilder.Append(this.ExpressionToString(rse.KeyPredicate.Values.First()));
      *  }
      *  else
      *  {
      *      bool addComma = false;
      *      foreach (var kvp in rse.KeyPredicate)
      *      {
      *          if (addComma)
      *          {
      *              this.uriBuilder.Append(UriHelper.COMMA);
      *          }
      *
      *          this.uriBuilder.Append(kvp.Key.Name);
      *          this.uriBuilder.Append(UriHelper.EQUALSSIGN);
      *          this.uriBuilder.Append(this.ExpressionToString(kvp.Value));
      *          addComma = true;
      *      }
      *  }
      *
      *  this.uriBuilder.Append(UriHelper.RIGHTPAREN);
      * }
      * else if (rse == this.leafResourceSet)
      * {
      *  this.uriBuilder.Append(UriHelper.LEFTPAREN);
      *  this.uriBuilder.Append(UriHelper.RIGHTPAREN);
      * }
      *
      * if (rse.CountOption == CountOption.ValueOnly)
      * {
      *  this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(UriHelper.DOLLARSIGN).Append(UriHelper.COUNT);
      *  this.EnsureMinimumVersion(2, 0);
      * }
      */
     this.VisitQueryOptions(rse);
     return(rse);
 }
예제 #4
0
        internal void VisitQueryOptions(ResourceExpression re)
        {
            if (re.HasQueryOptions)
            {
                ResourceSetExpression rse = re as ResourceSetExpression;
                if (rse != null)
                {
                    IEnumerator options = rse.SequenceQueryOptions.GetEnumerator();
                    while (options.MoveNext())
                    {
                        Expression             e  = (Expression)options.Current;
                        ResourceExpressionType et = (ResourceExpressionType)e.NodeType;
                        switch (et)
                        {
                        case ResourceExpressionType.RequestOptions:
                            this.VisitQueryOptionExpression((RequestOptionsQueryOptionExpression)e);
                            break;

                        case ResourceExpressionType.OperationContext:
                            this.VisitQueryOptionExpression((OperationContextQueryOptionExpression)e);
                            break;

                        case ResourceExpressionType.Resolver:
                            this.VisitQueryOptionExpression((EntityResolverQueryOptionExpression)e);
                            break;

                        case ResourceExpressionType.TakeQueryOption:
                            this.VisitQueryOptionExpression((TakeQueryOptionExpression)e);
                            break;

                        case ResourceExpressionType.FilterQueryOption:
                            this.VisitQueryOptionExpression((FilterQueryOptionExpression)e);
                            break;

                        default:
                            Debug.Assert(false, "Unexpected expression type " + (int)et);
                            break;
                        }
                    }
                }

                if (re.Projection != null && re.Projection.Paths.Count > 0)
                {
                    this.Projection    = re.Projection;
                    this.SelectColumns = re.Projection.Paths;
                }

                if (re.CustomQueryOptions.Count > 0)
                {
                    this.VisitCustomQueryOptions(re.CustomQueryOptions);
                }
            }
        }
예제 #5
0
        internal void OverrideInputReference(ResourceSetExpression newInput)
        {
            Debug.Assert(newInput != null, "Original resource set cannot be null");
            Debug.Assert(this.inputRef == null, "OverrideInputReference cannot be called if the target has already been referenced");

            InputReferenceExpression inputRef = newInput.inputRef;

            if (inputRef != null)
            {
                this.inputRef = inputRef;
                inputRef.OverrideTarget(this);
            }
        }
예제 #6
0
        internal override ResourceExpression CreateCloneWithNewType(Type type)
        {
            ResourceSetExpression rse = new ResourceSetExpression(
                type,
                this.Source,
                this.MemberExpression,
                TypeSystem.GetElementType(type),
                this.ExpandPaths.ToList(),
                this.CountOption,
                this.CustomQueryOptions.ToDictionary(kvp => kvp.Key, kvp => kvp.Value),
                this.Projection);

            rse.keyFilter            = this.keyFilter;
            rse.sequenceQueryOptions = this.sequenceQueryOptions;
            rse.transparentScope     = this.transparentScope;
            return(rse);
        }
예제 #7
0
        internal override Expression VisitMemberAccess(MemberExpression m)
        {
            if (this.inputSet == null ||
                !this.inputSet.HasTransparentScope)
            {
                return(base.VisitMemberAccess(m));
            }

            ParameterExpression  innerParamRef  = null;
            Stack <PropertyInfo> nestedAccesses = new Stack <PropertyInfo>();
            MemberExpression     memberRef      = m;

            while (memberRef != null &&
                   memberRef.Member.MemberType == MemberTypes.Property &&
                   memberRef.Expression != null)
            {
                nestedAccesses.Push((PropertyInfo)memberRef.Member);

                if (memberRef.Expression.NodeType == ExpressionType.Parameter)
                {
                    innerParamRef = (ParameterExpression)memberRef.Expression;
                }

                memberRef = memberRef.Expression as MemberExpression;
            }

            if (innerParamRef != this.inputParameter || nestedAccesses.Count == 0)
            {
                return(m);
            }

            ResourceExpression    target    = this.input;
            ResourceSetExpression targetSet = this.inputSet;
            bool transparentScopeTraversed  = false;

            while (nestedAccesses.Count > 0)
            {
                if (targetSet == null || !targetSet.HasTransparentScope)
                {
                    break;
                }

                PropertyInfo currentProp = nestedAccesses.Peek();

                if (currentProp.Name.Equals(targetSet.TransparentScope.Accessor, StringComparison.Ordinal))
                {
                    target = targetSet;
                    nestedAccesses.Pop();
                    transparentScopeTraversed = true;
                    continue;
                }

                Expression source;
                if (!targetSet.TransparentScope.SourceAccessors.TryGetValue(currentProp.Name, out source))
                {
                    break;
                }

                transparentScopeTraversed = true;
                nestedAccesses.Pop();
                Debug.Assert(source != null, "source != null -- otherwise ResourceBinder created an accessor to nowhere");
                InputReferenceExpression sourceReference = source as InputReferenceExpression;
                if (sourceReference == null)
                {
                    targetSet = source as ResourceSetExpression;
                    if (targetSet == null || !targetSet.HasTransparentScope)
                    {
                        target = (ResourceExpression)source;
                    }
                }
                else
                {
                    targetSet = sourceReference.Target as ResourceSetExpression;
                    target    = targetSet;
                }
            }

            if (!transparentScopeTraversed)
            {
                return(m);
            }

            Expression result = this.CreateReference(target);

            while (nestedAccesses.Count > 0)
            {
                result = Expression.Property(result, nestedAccesses.Pop());
            }

            return(result);
        }
예제 #8
0
 private InputBinder(ResourceExpression resource, ParameterExpression setReferenceParam)
 {
     this.input          = resource;
     this.inputSet       = resource as ResourceSetExpression;
     this.inputParameter = setReferenceParam;
 }