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; }
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); }
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); }
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); } } }
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); } }
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); }
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; }
private InputBinder(ResourceExpression resource, ParameterExpression setReferenceParam) { this.input = resource; this.inputSet = resource as ResourceSetExpression; this.inputParameter = setReferenceParam; }
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; }
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); }