/// <summary> /// Retargets this input reference to point to the resource set specified by <paramref name="newTarget"/>. /// </summary> /// <param name="newTarget">The <see cref="ResourceSetExpression"/> that this input reference should use as its target</param> 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 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 void OverrideInputReference(ResourceSetExpression newInput) { InputReferenceExpression inputRef = newInput.inputRef; if (inputRef != null) { base.inputRef = inputRef; inputRef.OverrideTarget(this); } }
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, rse.ResourceTypeAs, rse.UriVersion); } 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, rse.ResourceTypeAs, rse.UriVersion); } return(rse); }
internal override Expression VisitResourceSetExpression(ResourceSetExpression rse) { if (rse.NodeType == ((ExpressionType)0x2711)) { this.Visit(rse.Source); this.uriBuilder.Append('/').Append(this.ExpressionToString(rse.MemberExpression)); } else { string entitySetName = (string)((ConstantExpression)rse.MemberExpression).Value; this.uriBuilder.Append(this.context.BaseUriResolver.GetEntitySetUri(entitySetName)); } WebUtil.RaiseVersion(ref this.uriVersion, rse.UriVersion); if (rse.ResourceTypeAs != null) { this.uriBuilder.Append('/'); this.uriBuilder.Append(System.Data.Services.Client.UriHelper.GetEntityTypeNameForUriAndValidateMaxProtocolVersion(rse.ResourceTypeAs, this.context, ref this.uriVersion)); } if (rse.KeyPredicate != null) { this.uriBuilder.Append('('); if (rse.KeyPredicate.Count == 1) { this.uriBuilder.Append(this.ExpressionToString(rse.KeyPredicate.Values.First <ConstantExpression>())); } else { bool flag = false; foreach (KeyValuePair <PropertyInfo, ConstantExpression> pair in rse.KeyPredicate) { if (flag) { this.uriBuilder.Append(','); } this.uriBuilder.Append(pair.Key.Name); this.uriBuilder.Append('='); this.uriBuilder.Append(this.ExpressionToString(pair.Value)); flag = true; } } this.uriBuilder.Append(')'); } else if (rse == this.leafResourceSet) { this.uriBuilder.Append('('); this.uriBuilder.Append(')'); } if (rse.CountOption == CountOption.ValueOnly) { this.uriBuilder.Append('/').Append('$').Append("count"); WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2); } this.VisitQueryOptions(rse); return(rse); }
/// <summary> /// ResourceSetExpression visit method. /// </summary> /// <param name="rse">ResourceSetExpression expression to visit</param> /// <returns>Visited ResourceSetExpression expression</returns> 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); } 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) { // if resourceset is on the leaf, append () this.uriBuilder.Append(UriHelper.LEFTPAREN); this.uriBuilder.Append(UriHelper.RIGHTPAREN); } if (rse.CountOption == CountOption.ValueOnly) { // append $count segment: /$count this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(UriHelper.DOLLARSIGN).Append(UriHelper.COUNT); this.EnsureMinimumVersion(2, 0); } this.VisitQueryOptions(rse); return(rse); }
internal override Expression VisitMemberAccess(MemberExpression m) { if (m.Expression == this.oldLambdaParameter) { ResourceSetExpression projectionSource = this.projectionSource as ResourceSetExpression; if (((projectionSource != null) && projectionSource.HasTransparentScope) && (projectionSource.TransparentScope.Accessor == m.Member.Name)) { return(this.newLambdaParameter); } this.successfulRebind = false; } return(base.VisitMemberAccess(m)); }
/// <summary> /// Instructs this resource set expression to use the input reference expression from <paramref name="newInput"/> as it's /// own input reference, and to retarget the input reference from <paramref name="newInput"/> to this resource set expression. /// </summary> /// <param name="newInput">The resource set expression from which to take the input reference.</param> /// <remarks>Used exclusively by <see cref="ResourceBinder.RemoveTransparentScope"/>.</remarks> 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); } }
/// <summary> /// ResourceSetExpression visit method. /// </summary> /// <param name="rse">ResourceSetExpression expression to visit</param> /// <returns>Visited ResourceSetExpression expression</returns> 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, /*inPath*/ true)); } else { // this is a resource set expression // we should be at the very begining of // the URI Debug.Assert(this.uriBuilder.Length == 0, "The builder is not empty while we are adding a resourset"); string entitySetName = (String)((ConstantExpression)rse.MemberExpression).Value; this.uriBuilder.Append(this.context.BaseUriResolver.GetEntitySetUri(entitySetName)); } WebUtil.RaiseVersion(ref this.uriVersion, rse.UriVersion); if (rse.ResourceTypeAs != null) { this.uriBuilder.Append(UriHelper.FORWARDSLASH); UriHelper.AppendTypeSegment(this.uriBuilder, rse.ResourceTypeAs, this.context, /*inPath*/ true, ref this.uriVersion); } if (rse.KeyPredicateConjuncts.Count > 0) { this.context.UrlConventions.AppendKeyExpression(rse.GetKeyProperties(), kvp => kvp.Key.Name, kvp => kvp.Value.Value, this.uriBuilder); } else if (rse == this.leafResourceSet) { // if resourceset is on the leaf, append () this.uriBuilder.Append(UriHelper.LEFTPAREN); this.uriBuilder.Append(UriHelper.RIGHTPAREN); } if (rse.CountOption == CountOption.ValueOnly) { // append $count segment: /$count this.uriBuilder.Append(UriHelper.FORWARDSLASH).Append(UriHelper.DOLLARSIGN).Append(UriHelper.COUNT); WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2); } this.VisitQueryOptions(rse); return(rse); }
/// <summary> /// Cast ResourceSetExpression to new type /// </summary> 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 (m.Expression == this.oldLambdaParameter) { // Member is only a valid projection target if it is the target of the current scope ResourceSetExpression resourceSetExpression = this.projectionSource as ResourceSetExpression; if (resourceSetExpression != null && resourceSetExpression.HasTransparentScope && resourceSetExpression.TransparentScope.Accessor == m.Member.Name) { Debug.Assert(m.Type == this.newLambdaParameter.Type, "Should not be rewriting a parameter with a different type than the original"); return(this.newLambdaParameter); } else { this.successfulRebind = false; } } return(base.VisitMemberAccess(m)); }
/// <summary> /// Creates a clone of the current ResourceSetExpression with the specified expression and resource types /// </summary> /// <param name="newType">The new expression type</param> /// <param name="newResourceType">The new resource type</param> /// <returns>A copy of this with the new types</returns> private ResourceSetExpression CreateCloneWithNewTypes(Type newType, Type newResourceType) { ResourceSetExpression rse = new ResourceSetExpression( newType, this.source, this.MemberExpression, newResourceType, this.ExpandPaths.ToList(), this.CountOption, this.CustomQueryOptions.ToDictionary(kvp => kvp.Key, kvp => kvp.Value), this.Projection, this.ResourceTypeAs, this.UriVersion); if (this.keyPredicateConjuncts != null && this.keyPredicateConjuncts.Count > 0) { rse.SetKeyPredicate(this.keyPredicateConjuncts); } rse.keyFilter = this.keyFilter; rse.sequenceQueryOptions = this.sequenceQueryOptions; rse.transparentScope = this.transparentScope; return(rse); }
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 expression = null; Stack <PropertyInfo> stack = new Stack <PropertyInfo>(); for (MemberExpression expression2 = m; ((expression2 != null) && PlatformHelper.IsProperty(expression2.Member)) && (expression2.Expression != null); expression2 = expression2.Expression as MemberExpression) { stack.Push((PropertyInfo)expression2.Member); if (expression2.Expression.NodeType == ExpressionType.Parameter) { expression = (ParameterExpression)expression2.Expression; } } if ((expression != this.inputParameter) || (stack.Count == 0)) { return(m); } ResourceExpression input = this.input; ResourceSetExpression inputSet = this.inputSet; bool flag = false; while (stack.Count > 0) { if ((inputSet == null) || !inputSet.HasTransparentScope) { break; } PropertyInfo info = stack.Peek(); if (info.Name.Equals(inputSet.TransparentScope.Accessor, StringComparison.Ordinal)) { input = inputSet; stack.Pop(); flag = true; } else { Expression expression5; if (!inputSet.TransparentScope.SourceAccessors.TryGetValue(info.Name, out expression5)) { break; } flag = true; stack.Pop(); InputReferenceExpression expression6 = expression5 as InputReferenceExpression; if (expression6 == null) { inputSet = expression5 as ResourceSetExpression; if ((inputSet == null) || !inputSet.HasTransparentScope) { input = (ResourceExpression)expression5; } continue; } inputSet = expression6.Target as ResourceSetExpression; input = inputSet; } } if (!flag) { return(m); } Expression expression7 = this.CreateReference(input); while (stack.Count > 0) { expression7 = Expression.Property(expression7, stack.Pop()); } return(expression7); }
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); } 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 override Expression VisitMemberAccess(MemberExpression m) { if ((this.inputSet == null) || !this.inputSet.HasTransparentScope) { return base.VisitMemberAccess(m); } ParameterExpression expression = null; Stack<PropertyInfo> stack = new Stack<PropertyInfo>(); for (MemberExpression expression2 = m; ((expression2 != null) && PlatformHelper.IsProperty(expression2.Member)) && (expression2.Expression != null); expression2 = expression2.Expression as MemberExpression) { stack.Push((PropertyInfo) expression2.Member); if (expression2.Expression.NodeType == ExpressionType.Parameter) { expression = (ParameterExpression) expression2.Expression; } } if ((expression != this.inputParameter) || (stack.Count == 0)) { return m; } ResourceExpression input = this.input; ResourceSetExpression inputSet = this.inputSet; bool flag = false; while (stack.Count > 0) { if ((inputSet == null) || !inputSet.HasTransparentScope) { break; } PropertyInfo info = stack.Peek(); if (info.Name.Equals(inputSet.TransparentScope.Accessor, StringComparison.Ordinal)) { input = inputSet; stack.Pop(); flag = true; } else { Expression expression5; if (!inputSet.TransparentScope.SourceAccessors.TryGetValue(info.Name, out expression5)) { break; } flag = true; stack.Pop(); InputReferenceExpression expression6 = expression5 as InputReferenceExpression; if (expression6 == null) { inputSet = expression5 as ResourceSetExpression; if ((inputSet == null) || !inputSet.HasTransparentScope) { input = (ResourceExpression) expression5; } continue; } inputSet = expression6.Target as ResourceSetExpression; input = inputSet; } } if (!flag) { return m; } Expression expression7 = this.CreateReference(input); while (stack.Count > 0) { expression7 = Expression.Property(expression7, stack.Pop()); } return expression7; }
/// <summary> /// Resolves member accesses that represent transparent scope property accesses to the corresponding resource set, /// iff the input resource set is enclosed in a transparent scope and the specified MemberExpression represents /// such a property access. /// </summary> /// <param name="m">MemberExpression expression to visit</param> /// <returns> /// An InputReferenceExpression if the member access represents a transparent scope property /// access that can be resolved to a resource set in the path that produces the input resource set; /// otherwise the same MemberExpression is returned. /// </returns> internal override Expression VisitMemberAccess(MemberExpression m) { // If the current input resource set is not enclosed in a transparent scope, then this // MemberExpression cannot represent a valid transparent scope access based on the input parameter. 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 && PlatformHelper.IsProperty(memberRef.Member) && memberRef.Expression != null) { nestedAccesses.Push((PropertyInfo)memberRef.Member); if (memberRef.Expression.NodeType == ExpressionType.Parameter) { innerParamRef = (ParameterExpression)memberRef.Expression; } memberRef = memberRef.Expression as MemberExpression; } // Only continue if the inner non-MemberExpression is the input reference ParameterExpression and // at least one property reference is present - otherwise this cannot be a transparent scope access. if (innerParamRef != this.inputParameter || nestedAccesses.Count == 0) { return(m); } ResourceExpression target = this.input; ResourceSetExpression targetSet = this.inputSet; bool transparentScopeTraversed = false; // Process all the traversals through transparent scopes. while (nestedAccesses.Count > 0) { if (targetSet == null || !targetSet.HasTransparentScope) { break; } // Peek the property; pop it once it's consumed // (it could be a non-transparent-identifier access). PropertyInfo currentProp = nestedAccesses.Peek(); // If this is the accessor for the target, then the member // refers to the target itself. if (currentProp.Name.Equals(targetSet.TransparentScope.Accessor, StringComparison.Ordinal)) { target = targetSet; nestedAccesses.Pop(); transparentScopeTraversed = true; continue; } // This member could also be one of the in-scope sources of the target. 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 no traversals were made, the original expression is OK. if (!transparentScopeTraversed) { return(m); } // Process traversals after the transparent scope. Expression result = this.CreateReference(target); while (nestedAccesses.Count > 0) { result = Expression.Property(result, nestedAccesses.Pop()); } return(result); }
internal void VisitQueryOptions(ResourceExpression re) { bool flag = false; if (re.HasQueryOptions) { this.uriBuilder.Append('?'); ResourceSetExpression expression = re as ResourceSetExpression; if (expression != null) { IEnumerator enumerator = expression.SequenceQueryOptions.GetEnumerator(); while (enumerator.MoveNext()) { if (flag) { this.uriBuilder.Append('&'); } Expression current = (Expression)enumerator.Current; switch (current.NodeType) { case ((ExpressionType)0x2713): this.VisitQueryOptionExpression((TakeQueryOptionExpression)current); break; case ((ExpressionType)0x2714): this.VisitQueryOptionExpression((SkipQueryOptionExpression)current); break; case ((ExpressionType)0x2715): this.VisitQueryOptionExpression((OrderByQueryOptionExpression)current); break; case ((ExpressionType)0x2716): this.VisitQueryOptionExpression((FilterQueryOptionExpression)current); break; } flag = true; } } if (re.ExpandPaths.Count > 0) { if (flag) { this.uriBuilder.Append('&'); } this.VisitExpandOptions(re.ExpandPaths); flag = true; } if ((re.Projection != null) && (re.Projection.Paths.Count > 0)) { if (flag) { this.uriBuilder.Append('&'); } this.VisitProjectionPaths(re.Projection.Paths); flag = true; } if (re.CountOption == CountOption.InlineAll) { if (flag) { this.uriBuilder.Append('&'); } this.VisitCountOptions(); flag = true; } if (re.CustomQueryOptions.Count > 0) { if (flag) { this.uriBuilder.Append('&'); } this.VisitCustomQueryOptions(re.CustomQueryOptions); flag = true; } } }
private InputBinder(ResourceExpression resource, ParameterExpression setReferenceParam) { this.input = resource; this.inputSet = resource as ResourceSetExpression; this.inputParameter = setReferenceParam; }
internal void VisitQueryOptions(ResourceExpression re) { bool needAmpersand = false; if (re.HasQueryOptions) { this.uriBuilder.Append(UriHelper.QUESTIONMARK); ResourceSetExpression rse = re as ResourceSetExpression; if (rse != null) { IEnumerator options = rse.SequenceQueryOptions.GetEnumerator(); while (options.MoveNext()) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } Expression e = ((Expression)options.Current); ResourceExpressionType et = (ResourceExpressionType)e.NodeType; switch (et) { case ResourceExpressionType.SkipQueryOption: this.VisitQueryOptionExpression((SkipQueryOptionExpression)e); break; case ResourceExpressionType.TakeQueryOption: this.VisitQueryOptionExpression((TakeQueryOptionExpression)e); break; case ResourceExpressionType.OrderByQueryOption: this.VisitQueryOptionExpression((OrderByQueryOptionExpression)e); break; case ResourceExpressionType.FilterQueryOption: this.VisitQueryOptionExpression((FilterQueryOptionExpression)e); break; default: Debug.Assert(false, "Unexpected expression type " + (int)et); break; } needAmpersand = true; } } if (re.ExpandPaths.Count > 0) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } this.VisitExpandOptions(re.ExpandPaths); needAmpersand = true; } if (re.Projection != null && re.Projection.Paths.Count > 0) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } this.VisitProjectionPaths(re.Projection.Paths); needAmpersand = true; } if (re.CountOption == CountOption.InlineAll) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } this.VisitCountOptions(); needAmpersand = true; } if (re.CustomQueryOptions.Count > 0) { if (needAmpersand) { this.uriBuilder.Append(UriHelper.AMPERSAND); } this.VisitCustomQueryOptions(re.CustomQueryOptions); needAmpersand = true; } } }
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 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); }
internal void OverrideTarget(ResourceSetExpression newTarget) { this.target = newTarget; }
internal override Expression VisitResourceSetExpression(ResourceSetExpression rse) { if (rse.NodeType == ((ExpressionType) 0x2711)) { this.Visit(rse.Source); this.uriBuilder.Append('/').Append(this.ExpressionToString(rse.MemberExpression)); } else { string entitySetName = (string) ((ConstantExpression) rse.MemberExpression).Value; this.uriBuilder.Append(this.context.BaseUriResolver.GetEntitySetUri(entitySetName)); } WebUtil.RaiseVersion(ref this.uriVersion, rse.UriVersion); if (rse.ResourceTypeAs != null) { this.uriBuilder.Append('/'); this.uriBuilder.Append(System.Data.Services.Client.UriHelper.GetEntityTypeNameForUriAndValidateMaxProtocolVersion(rse.ResourceTypeAs, this.context, ref this.uriVersion)); } if (rse.KeyPredicate != null) { this.uriBuilder.Append('('); if (rse.KeyPredicate.Count == 1) { this.uriBuilder.Append(this.ExpressionToString(rse.KeyPredicate.Values.First<ConstantExpression>())); } else { bool flag = false; foreach (KeyValuePair<PropertyInfo, ConstantExpression> pair in rse.KeyPredicate) { if (flag) { this.uriBuilder.Append(','); } this.uriBuilder.Append(pair.Key.Name); this.uriBuilder.Append('='); this.uriBuilder.Append(this.ExpressionToString(pair.Value)); flag = true; } } this.uriBuilder.Append(')'); } else if (rse == this.leafResourceSet) { this.uriBuilder.Append('('); this.uriBuilder.Append(')'); } if (rse.CountOption == CountOption.ValueOnly) { this.uriBuilder.Append('/').Append('$').Append("count"); WebUtil.RaiseVersion(ref this.uriVersion, Util.DataServiceVersion2); } this.VisitQueryOptions(rse); return rse; }