Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataWeb / Client / System / Data / Services / Client / ALinq / InputBinder.cs / 1 / InputBinder.cs
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Expression visitor that converts ParameterReference or (MemberAccess*)\ParameterReference expressions
// into references to one or more ResourceSetExpressions. After processing, the specified expression tree
// will contain InputReferenceExpressions instead of these parameter or parameter and property references.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Client
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Diagnostics;
///
/// Replaces references to resource sets - represented as either ParameterExpressions or one or more
/// MemberExpressions over a ParameterExpression - with an appropriate InputReferenceExpression that
/// indicates which resource set is referenced; effective 'binds' the argument expression to the
/// resource sets that it references.
///
internal sealed class InputBinder : DataServiceExpressionVisitor
{
/// Tracks which resource sets are referenced by the argument expression
private readonly HashSet referencedInputs = new HashSet(EqualityComparer.Default);
/// Resource from which valid references must start; if no set with a transparent scope is present, only direct references to this resource will be rebound
private readonly ResourceExpression input;
/// The input resource, as a resource set (may be null if the input is actually a NavigationPropertySingletonExpression)
private readonly ResourceSetExpression inputSet;
/// The ParameterExpression that, if encountered, indicates a reference to the input resource set
private readonly ParameterExpression inputParameter;
///
/// Constructs a new InputBinder based on the specified input resource set, which is represented by the specified ParameterExpression.
///
/// The current input resource from which valid references must start
/// The parameter that must be referenced in order to refer to the specified input resource set
private InputBinder(ResourceExpression resource, ParameterExpression setReferenceParam)
{
this.input = resource;
this.inputSet = resource as ResourceSetExpression;
this.inputParameter = setReferenceParam;
}
///
/// Replaces Lambda parameter references or transparent scope property accesses over those Lambda
/// parameter references with s to the appropriate corresponding
/// s, based on the 'input' ResourceSetExpression to which the
/// Lambda is logically applied and any enclosing transparent scope applied to that input resource set.
///
/// The parameter to rebind
///
/// The 'current input' resource set - either the root resource set or the
/// rightmost set in the navigation chain.
/// The Lambda parameter that represents a reference to the 'input' set
/// A list that will be populated with the resource sets that were referenced by the rebound expression
///
/// The rebound version of where MemberExpression/ParameterExpressions that
/// represent resource set references have been replaced with appropriate InputReferenceExpressions.
///
internal static Expression Bind(Expression e, ResourceExpression currentInput, ParameterExpression inputParameter, List referencedInputs)
{
Debug.Assert(e != null, "Expression cannot be null");
Debug.Assert(currentInput != null, "A current input resource set is required");
Debug.Assert(inputParameter != null, "The input lambda parameter is required");
Debug.Assert(referencedInputs != null, "The referenced inputs list is required");
InputBinder binder = new InputBinder(currentInput, inputParameter);
e = binder.Visit(e);
referencedInputs.AddRange(binder.referencedInputs);
return e;
}
///
/// 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.
///
/// MemberExpression expression to visit
///
/// 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.
///
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 nestedAccesses = new Stack();
MemberExpression memberRef = m;
while (memberRef != null &&
memberRef.Member.MemberType == MemberTypes.Property &&
memberRef.Expression != null)
{
nestedAccesses.Push((PropertyInfo)memberRef.Member);
if (memberRef.Expression != null && 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)
{
ResourceExpression target = this.input;
ResourceSetExpression targetSet = this.inputSet;
Expression retExpr = null;
while (nestedAccesses.Count > 0)
{
PropertyInfo currentProp = nestedAccesses.Pop();
if (retExpr == null && targetSet != null && targetSet.HasTransparentScope)
{
if (currentProp.Name.Equals(targetSet.TransparentScope.Accessor, StringComparison.Ordinal))
{
retExpr = this.CreateReference(targetSet);
}
else
{
if (currentProp.Name.Equals(targetSet.TransparentScope.SourceAccessor, StringComparison.Ordinal))
{
target = (ResourceExpression)targetSet.Source;
targetSet = target as ResourceSetExpression;
if (targetSet == null || !targetSet.HasTransparentScope)
{
retExpr = this.CreateReference(target);
}
}
else
{
// The property reference is not to the resource set or it's source resource set.
// This implies the transparent scope is not actually a transparent scope but a row constructor,
// and is not supported.
return m;
}
}
}
else
{
retExpr = Expression.Property(retExpr, currentProp);
}
}
return retExpr;
}
return m;
}
///
/// Converts a parameter reference to the input resource set into an InputReferenceExpression,
/// iff the parameter reference is to the parameter expression that represents the input resource set
/// and the input resource set is not enclosed in a transparent scope.
///
/// The parameter reference expression
///
/// An InputReferenceExpression if the parameter reference is to the input parameter;
/// otherwise the same parameter reference expression
///
internal override Expression VisitParameter(ParameterExpression p)
{
// If the input Resource Set is not enclosed in a transparent scope,
// and the parameter reference is a reference to the Lambda parameter
// that represents the input resource set, then return an InputReferenceExpression.
if ((this.inputSet == null || !this.inputSet.HasTransparentScope) &&
p == this.inputParameter)
{
return this.CreateReference(this.input);
}
else
{
return base.VisitParameter(p);
}
}
///
/// Returns an that references the specified resource set,
/// and also adds the the resource set to the hashset of resource sets that were referenced by the
/// expression that is being rebound.
///
/// The resource(set) for which a reference was found
/// An InputReferenceExpression that represents a reference to the specified resource set
private Expression CreateReference(ResourceExpression resource)
{
this.referencedInputs.Add(resource);
return resource.CreateReference();
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
//----------------------------------------------------------------------
//
// Copyright (c) Microsoft Corporation. All rights reserved.
//
//
// Expression visitor that converts ParameterReference or (MemberAccess*)\ParameterReference expressions
// into references to one or more ResourceSetExpressions. After processing, the specified expression tree
// will contain InputReferenceExpressions instead of these parameter or parameter and property references.
//
//
// @owner [....]
//---------------------------------------------------------------------
namespace System.Data.Services.Client
{
using System;
using System.Collections.Generic;
using System.Text;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
using System.Diagnostics;
///
/// Replaces references to resource sets - represented as either ParameterExpressions or one or more
/// MemberExpressions over a ParameterExpression - with an appropriate InputReferenceExpression that
/// indicates which resource set is referenced; effective 'binds' the argument expression to the
/// resource sets that it references.
///
internal sealed class InputBinder : DataServiceExpressionVisitor
{
/// Tracks which resource sets are referenced by the argument expression
private readonly HashSet referencedInputs = new HashSet(EqualityComparer.Default);
/// Resource from which valid references must start; if no set with a transparent scope is present, only direct references to this resource will be rebound
private readonly ResourceExpression input;
/// The input resource, as a resource set (may be null if the input is actually a NavigationPropertySingletonExpression)
private readonly ResourceSetExpression inputSet;
/// The ParameterExpression that, if encountered, indicates a reference to the input resource set
private readonly ParameterExpression inputParameter;
///
/// Constructs a new InputBinder based on the specified input resource set, which is represented by the specified ParameterExpression.
///
/// The current input resource from which valid references must start
/// The parameter that must be referenced in order to refer to the specified input resource set
private InputBinder(ResourceExpression resource, ParameterExpression setReferenceParam)
{
this.input = resource;
this.inputSet = resource as ResourceSetExpression;
this.inputParameter = setReferenceParam;
}
///
/// Replaces Lambda parameter references or transparent scope property accesses over those Lambda
/// parameter references with s to the appropriate corresponding
/// s, based on the 'input' ResourceSetExpression to which the
/// Lambda is logically applied and any enclosing transparent scope applied to that input resource set.
///
/// The parameter to rebind
///
/// The 'current input' resource set - either the root resource set or the
/// rightmost set in the navigation chain.
/// The Lambda parameter that represents a reference to the 'input' set
/// A list that will be populated with the resource sets that were referenced by the rebound expression
///
/// The rebound version of where MemberExpression/ParameterExpressions that
/// represent resource set references have been replaced with appropriate InputReferenceExpressions.
///
internal static Expression Bind(Expression e, ResourceExpression currentInput, ParameterExpression inputParameter, List referencedInputs)
{
Debug.Assert(e != null, "Expression cannot be null");
Debug.Assert(currentInput != null, "A current input resource set is required");
Debug.Assert(inputParameter != null, "The input lambda parameter is required");
Debug.Assert(referencedInputs != null, "The referenced inputs list is required");
InputBinder binder = new InputBinder(currentInput, inputParameter);
e = binder.Visit(e);
referencedInputs.AddRange(binder.referencedInputs);
return e;
}
///
/// 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.
///
/// MemberExpression expression to visit
///
/// 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.
///
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 nestedAccesses = new Stack();
MemberExpression memberRef = m;
while (memberRef != null &&
memberRef.Member.MemberType == MemberTypes.Property &&
memberRef.Expression != null)
{
nestedAccesses.Push((PropertyInfo)memberRef.Member);
if (memberRef.Expression != null && 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)
{
ResourceExpression target = this.input;
ResourceSetExpression targetSet = this.inputSet;
Expression retExpr = null;
while (nestedAccesses.Count > 0)
{
PropertyInfo currentProp = nestedAccesses.Pop();
if (retExpr == null && targetSet != null && targetSet.HasTransparentScope)
{
if (currentProp.Name.Equals(targetSet.TransparentScope.Accessor, StringComparison.Ordinal))
{
retExpr = this.CreateReference(targetSet);
}
else
{
if (currentProp.Name.Equals(targetSet.TransparentScope.SourceAccessor, StringComparison.Ordinal))
{
target = (ResourceExpression)targetSet.Source;
targetSet = target as ResourceSetExpression;
if (targetSet == null || !targetSet.HasTransparentScope)
{
retExpr = this.CreateReference(target);
}
}
else
{
// The property reference is not to the resource set or it's source resource set.
// This implies the transparent scope is not actually a transparent scope but a row constructor,
// and is not supported.
return m;
}
}
}
else
{
retExpr = Expression.Property(retExpr, currentProp);
}
}
return retExpr;
}
return m;
}
///
/// Converts a parameter reference to the input resource set into an InputReferenceExpression,
/// iff the parameter reference is to the parameter expression that represents the input resource set
/// and the input resource set is not enclosed in a transparent scope.
///
/// The parameter reference expression
///
/// An InputReferenceExpression if the parameter reference is to the input parameter;
/// otherwise the same parameter reference expression
///
internal override Expression VisitParameter(ParameterExpression p)
{
// If the input Resource Set is not enclosed in a transparent scope,
// and the parameter reference is a reference to the Lambda parameter
// that represents the input resource set, then return an InputReferenceExpression.
if ((this.inputSet == null || !this.inputSet.HasTransparentScope) &&
p == this.inputParameter)
{
return this.CreateReference(this.input);
}
else
{
return base.VisitParameter(p);
}
}
///
/// Returns an that references the specified resource set,
/// and also adds the the resource set to the hashset of resource sets that were referenced by the
/// expression that is being rebound.
///
/// The resource(set) for which a reference was found
/// An InputReferenceExpression that represents a reference to the specified resource set
private Expression CreateReference(ResourceExpression resource)
{
this.referencedInputs.Add(resource);
return resource.CreateReference();
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- PackWebResponse.cs
- ProgressChangedEventArgs.cs
- UnitySerializationHolder.cs
- BitVec.cs
- XmlArrayAttribute.cs
- ListViewContainer.cs
- Int32AnimationBase.cs
- XmlTextWriter.cs
- DataListItem.cs
- IdentitySection.cs
- JapaneseLunisolarCalendar.cs
- SecureUICommand.cs
- KnownTypes.cs
- MaskDescriptors.cs
- Int64Converter.cs
- XmlChildEnumerator.cs
- TextRangeEdit.cs
- ISFClipboardData.cs
- QuaternionRotation3D.cs
- TextEffectCollection.cs
- SqlFactory.cs
- OnOperation.cs
- OperandQuery.cs
- ExpressionVisitor.cs
- AlphabeticalEnumConverter.cs
- ListBindableAttribute.cs
- HttpException.cs
- WithStatement.cs
- arc.cs
- AndCondition.cs
- EntityContainerEmitter.cs
- SqlInternalConnectionSmi.cs
- StreamUpdate.cs
- DrawingServices.cs
- TraceLevelStore.cs
- SmtpSection.cs
- GiveFeedbackEvent.cs
- TextEditorCharacters.cs
- BitmapEffectGroup.cs
- ResourceIDHelper.cs
- StringFunctions.cs
- XmlWriterSettings.cs
- SettingsPropertyValueCollection.cs
- CompositeActivityTypeDescriptor.cs
- Normalizer.cs
- DataSourceHelper.cs
- EnterpriseServicesHelper.cs
- GridView.cs
- CurrencyManager.cs
- IgnoreSectionHandler.cs
- Typeface.cs
- EntitySqlQueryBuilder.cs
- ControlPropertyNameConverter.cs
- CharacterHit.cs
- TableItemStyle.cs
- FillRuleValidation.cs
- RemotingException.cs
- DateTime.cs
- FileDialogPermission.cs
- SectionVisual.cs
- BatchParser.cs
- XmlHierarchicalEnumerable.cs
- Base64Encoder.cs
- SQLByte.cs
- LineGeometry.cs
- XmlTextWriter.cs
- ImportCatalogPart.cs
- ElementAction.cs
- RoleService.cs
- RegexFCD.cs
- XmlCDATASection.cs
- ServiceDescription.cs
- TextTreeObjectNode.cs
- FileDialogCustomPlace.cs
- IgnoreSectionHandler.cs
- WebMessageFormatHelper.cs
- TransformedBitmap.cs
- SQLInt16Storage.cs
- DateTimeSerializationSection.cs
- WizardForm.cs
- NamedPipeConnectionPool.cs
- DownloadProgressEventArgs.cs
- CompositeDispatchFormatter.cs
- CodePageUtils.cs
- CounterCreationData.cs
- PropertyHelper.cs
- ButtonStandardAdapter.cs
- GenericRootAutomationPeer.cs
- ConfigXmlCDataSection.cs
- OleDbCommandBuilder.cs
- UidManager.cs
- DataControlFieldCell.cs
- DataGridViewAutoSizeModeEventArgs.cs
- DeviceSpecificDialogCachedState.cs
- EntityClassGenerator.cs
- Size.cs
- ZipArchive.cs
- ListViewInsertEventArgs.cs
- TaiwanCalendar.cs
- RtfControls.cs