Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / Internal / ViewSimplifier.cs / 1 / ViewSimplifier.cs
//---------------------------------------------------------------------- //// Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; using System.Collections.Generic; using System.Data.Metadata.Edm; using System.Diagnostics; using System.Data.Common.Utils; using System.Linq; using System.Globalization; namespace System.Data.Common.CommandTrees.Internal { ////// Utility class that walks a mapping view and returns a simplified expression with projection /// nodes collapsed. Specifically recognizes the following common pattern in mapping views: /// /// outerProject(outerBinding(innerProject(innerBinding, innerNew)), outerProjection) /// /// Recognizes simple disciminator patterns of the form: /// /// select /// case when Disc = value1 then value Type1(...) /// case when Disc = value2 then value Type2(...) /// ... /// /// Recognizes redundant case statement of the form: /// /// select /// case when (case when Predicate1 then true else false) ... /// /// internal static class ViewSimplifier { internal static DbQueryCommandTree SimplifyView(DbQueryCommandTree view) { view = view.Clone(); view.Replace(CollapseProject); view.Replace(SimplifyCaseStatements); return view; } ////// This expression replacer delegate supports collapsing a nested projection matching the pattern described above. /// /// For instance: /// /// select T.a as x, T.b as y, true as z from (select E.a as x, E.b as y from Extent E) /// /// resolves to: /// /// select E.a, E.b, true as z from Extent E /// /// In general, /// /// outerProject( /// outerBinding( /// innerProject(innerBinding, innerNew) /// ), /// outerNew) /// /// resolves to: /// /// replacementOuterProject( /// innerBinding, /// replacementOuterNew) /// /// The outer projection is bound to the inner input source (outerBinding -> innerBinding) and /// the outer new instance expression has its properties remapped to the inner new instance /// expression member expressions. /// private static void CollapseProject(ExpressionReplacement replacement) { // retrieve the replacement candidate DbExpression candidate = replacement.Current; DbProjectExpression outerProject; DbExpression outerProjection; DbProjectExpression innerProject; DbNewInstanceExpression innerNew; // determine if the candidate matches the pattern we know how to rewrite if (TryMatchNestedProjectPattern(candidate, out outerProject, out outerProjection, out innerProject, out innerNew)) { CollapseNestedProjection(replacement, outerProject, outerProjection, innerProject, innerNew); } } ////// determines if an expression is of the form outerProject(outerProjection(innerProject(innerNew))), /// returning these elements /// private static bool TryMatchNestedProjectPattern(DbExpression outerCandidate, out DbProjectExpression outerProject, out DbExpression outerProjection, out DbProjectExpression innerProject, out DbNewInstanceExpression innerNew) { // init output parameters outerProject = null; outerProjection = null; innerProject = null; innerNew = null; // check the pattern if (outerCandidate.ExpressionKind != DbExpressionKind.Project) { return false; } outerProject = (DbProjectExpression)outerCandidate; outerProjection = outerProject.Projection; if (outerProject.Input.Expression.ExpressionKind != DbExpressionKind.Project) { return false; } innerProject = (DbProjectExpression)outerProject.Input.Expression; if (innerProject.Projection.ExpressionKind != DbExpressionKind.NewInstance) { return false; } innerNew = (DbNewInstanceExpression)innerProject.Projection; return true; } ////// Collapses outerProject(outerProjection(innerProject(innerNew))) /// private static void CollapseNestedProjection(ExpressionReplacement replacement, DbProjectExpression outerProject, DbExpression outerProjection, DbProjectExpression innerProject, DbNewInstanceExpression innerNew) { replacement.VisitReplacement = true; // continue collapsing projection until the pattern no longer matches // get membername -> expression bindings for the inner select so that we know how map property // references to the inner projectio Dictionarybindings = new Dictionary (innerNew.Arguments.Count); TypeUsage innerResultTypeUsage = innerNew.ResultType; RowType innerResultType = (RowType)innerResultTypeUsage.EdmType; for (int ordinal = 0; ordinal < innerResultType.Members.Count; ordinal++) { bindings[innerResultType.Members[ordinal].Name] = innerNew.Arguments[ordinal]; } // initialize an expression replacer that knows how to map arguments to the outer projection // to the inner projection source ProjectionCollapser collapser = new ProjectionCollapser(bindings, outerProject.Input); ExpressionReplacer replacer = new ExpressionReplacer(collapser.CollapseProjection); // replace all property references to the inner projection var replacementOuterProjection = replacer.Replace(outerProjection); DbProjectExpression replacementOuterProject = outerProject.CommandTree.CreateProjectExpression( innerProject.Input, replacementOuterProjection); // make sure the collapsing was successful; if not, give up on simplification if (collapser.IsDoomed) { return; } // set replacement value so that the expression replacer infrastructure can substitute // the collapsed projection in the expression tree replacement.Replacement = replacementOuterProject; } private static void SimplifyCaseStatements(ExpressionReplacement replacement) { var candidate = replacement.Current; if (candidate.ExpressionKind != DbExpressionKind.Case) { return; } var caseExpression = (DbCaseExpression)replacement.Current; // try simplifying predicates bool predicateSimplified = false; List rewrittenPredicates = new List (caseExpression.When.Count); foreach (var when in caseExpression.When) { DbExpression simplifiedPredicate; if (TrySimplifyPredicate(when, out simplifiedPredicate)) { rewrittenPredicates.Add(simplifiedPredicate); predicateSimplified = true; } else { rewrittenPredicates.Add(when); } } if (!predicateSimplified) { return; } replacement.Replacement = caseExpression.CommandTree.CreateCaseExpression( rewrittenPredicates, caseExpression.Then, caseExpression.Else); replacement.VisitReplacement = true; } private static bool TrySimplifyPredicate(DbExpression predicate, out DbExpression simplified) { simplified = null; if (predicate.ExpressionKind != DbExpressionKind.Case) { return false; } var caseExpression = (DbCaseExpression)predicate; if (caseExpression.Then.Count != 1 && caseExpression.Then[0].ExpressionKind == DbExpressionKind.Constant) { return false; } var then = (DbConstantExpression)caseExpression.Then[0]; if (!true.Equals(then.Value)) { return false; } if (caseExpression.Else != null) { if (caseExpression.Else.ExpressionKind != DbExpressionKind.Constant) { return false; } var when = (DbConstantExpression)caseExpression.Else; if (!false.Equals(when.Value)) { return false; } } simplified = caseExpression.When[0]; return true; } /// /// replacer used to simplify argument value in a new instance expression OuterNew from /// an expression of the form: /// /// outerProject(outerBinding(innerProject(innerBinding, innerNew)), outerProjection) /// /// The replacer collapses the outer project terms to point at the innerNew expression. /// Where possible, VarRef_outer.Property_outer is collapsed to VarRef_inner.Property. /// private class ProjectionCollapser { // the replacer context keeps track of member bindings for var refs and the expression // binding for the outer projection being remapped private Dictionarym_varRefMemberBindings; private DbExpressionBinding m_outerBinding; private bool m_doomed; internal ProjectionCollapser(Dictionary varRefMemberBindings, DbExpressionBinding outerBinding) { m_varRefMemberBindings = varRefMemberBindings; m_outerBinding = outerBinding; } // replacer delegate that identifies the Property(VarRef "Outer binding") pattern, // and remaps the property to the appropriate inner projection member internal void CollapseProjection(ExpressionReplacement replacement) { // check for a property of the outer projection binding (that can be remapped) if (replacement.Current.ExpressionKind == DbExpressionKind.Property) { var property = (DbPropertyExpression)replacement.Current; if (property.Instance.ExpressionKind == DbExpressionKind.VariableReference && IsOuterBindingVarRef((DbVariableReferenceExpression)property.Instance)) { replacement.VisitReplacement = false; replacement.Replacement = m_varRefMemberBindings[property.Property.Name]; } } else if (replacement.Current.ExpressionKind == DbExpressionKind.VariableReference) { // if we encounter an unsubstitutued var ref, give up... var varRef = (DbVariableReferenceExpression)replacement.Current; if (IsOuterBindingVarRef(varRef)) { m_doomed = true; } } } /// /// Heuristic check to make sure the var ref is the one we're supposed to be replacing. /// private bool IsOuterBindingVarRef(DbVariableReferenceExpression varRef) { return varRef.VariableName == m_outerBinding.VariableName; } ////// Returns a value indicating that the transformation has failed. /// internal bool IsDoomed { get { return m_doomed; } } } /* private abstract class DiscriminatorValueCollection { ////// Add a new discriminator value. Returns true if the value is unique. /// internal abstract bool TryAddDiscriminatorValue(object value); ////// Associate a discriminator value with the given type. Returns true if the value is known. /// internal abstract bool TryAddDiscriminatorValueAssignment(object value, EntityType entityType); ////// /// internal abstract bool TryAssignDefaultType(EntityType entityType); private class TypedDiscriminatorValueCollection{ private readonly TryConvert _convert; private readonly Func , T> _generateUniqueDiscriminator; private readonly HashSet _discriminatorValues; private readonly Dictionary _discriminatorAssignments; } private delegate bool TryConvert (object input, out T output); } * */ } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. //---------------------------------------------------------------------- // // Copyright (c) Microsoft Corporation. All rights reserved. // // // @owner [....] // @backupOwner [....] //--------------------------------------------------------------------- using System.Data.Common.CommandTrees; using System.Collections.Generic; using System.Data.Metadata.Edm; using System.Diagnostics; using System.Data.Common.Utils; using System.Linq; using System.Globalization; namespace System.Data.Common.CommandTrees.Internal { ////// Utility class that walks a mapping view and returns a simplified expression with projection /// nodes collapsed. Specifically recognizes the following common pattern in mapping views: /// /// outerProject(outerBinding(innerProject(innerBinding, innerNew)), outerProjection) /// /// Recognizes simple disciminator patterns of the form: /// /// select /// case when Disc = value1 then value Type1(...) /// case when Disc = value2 then value Type2(...) /// ... /// /// Recognizes redundant case statement of the form: /// /// select /// case when (case when Predicate1 then true else false) ... /// /// internal static class ViewSimplifier { internal static DbQueryCommandTree SimplifyView(DbQueryCommandTree view) { view = view.Clone(); view.Replace(CollapseProject); view.Replace(SimplifyCaseStatements); return view; } ////// This expression replacer delegate supports collapsing a nested projection matching the pattern described above. /// /// For instance: /// /// select T.a as x, T.b as y, true as z from (select E.a as x, E.b as y from Extent E) /// /// resolves to: /// /// select E.a, E.b, true as z from Extent E /// /// In general, /// /// outerProject( /// outerBinding( /// innerProject(innerBinding, innerNew) /// ), /// outerNew) /// /// resolves to: /// /// replacementOuterProject( /// innerBinding, /// replacementOuterNew) /// /// The outer projection is bound to the inner input source (outerBinding -> innerBinding) and /// the outer new instance expression has its properties remapped to the inner new instance /// expression member expressions. /// private static void CollapseProject(ExpressionReplacement replacement) { // retrieve the replacement candidate DbExpression candidate = replacement.Current; DbProjectExpression outerProject; DbExpression outerProjection; DbProjectExpression innerProject; DbNewInstanceExpression innerNew; // determine if the candidate matches the pattern we know how to rewrite if (TryMatchNestedProjectPattern(candidate, out outerProject, out outerProjection, out innerProject, out innerNew)) { CollapseNestedProjection(replacement, outerProject, outerProjection, innerProject, innerNew); } } ////// determines if an expression is of the form outerProject(outerProjection(innerProject(innerNew))), /// returning these elements /// private static bool TryMatchNestedProjectPattern(DbExpression outerCandidate, out DbProjectExpression outerProject, out DbExpression outerProjection, out DbProjectExpression innerProject, out DbNewInstanceExpression innerNew) { // init output parameters outerProject = null; outerProjection = null; innerProject = null; innerNew = null; // check the pattern if (outerCandidate.ExpressionKind != DbExpressionKind.Project) { return false; } outerProject = (DbProjectExpression)outerCandidate; outerProjection = outerProject.Projection; if (outerProject.Input.Expression.ExpressionKind != DbExpressionKind.Project) { return false; } innerProject = (DbProjectExpression)outerProject.Input.Expression; if (innerProject.Projection.ExpressionKind != DbExpressionKind.NewInstance) { return false; } innerNew = (DbNewInstanceExpression)innerProject.Projection; return true; } ////// Collapses outerProject(outerProjection(innerProject(innerNew))) /// private static void CollapseNestedProjection(ExpressionReplacement replacement, DbProjectExpression outerProject, DbExpression outerProjection, DbProjectExpression innerProject, DbNewInstanceExpression innerNew) { replacement.VisitReplacement = true; // continue collapsing projection until the pattern no longer matches // get membername -> expression bindings for the inner select so that we know how map property // references to the inner projectio Dictionarybindings = new Dictionary (innerNew.Arguments.Count); TypeUsage innerResultTypeUsage = innerNew.ResultType; RowType innerResultType = (RowType)innerResultTypeUsage.EdmType; for (int ordinal = 0; ordinal < innerResultType.Members.Count; ordinal++) { bindings[innerResultType.Members[ordinal].Name] = innerNew.Arguments[ordinal]; } // initialize an expression replacer that knows how to map arguments to the outer projection // to the inner projection source ProjectionCollapser collapser = new ProjectionCollapser(bindings, outerProject.Input); ExpressionReplacer replacer = new ExpressionReplacer(collapser.CollapseProjection); // replace all property references to the inner projection var replacementOuterProjection = replacer.Replace(outerProjection); DbProjectExpression replacementOuterProject = outerProject.CommandTree.CreateProjectExpression( innerProject.Input, replacementOuterProjection); // make sure the collapsing was successful; if not, give up on simplification if (collapser.IsDoomed) { return; } // set replacement value so that the expression replacer infrastructure can substitute // the collapsed projection in the expression tree replacement.Replacement = replacementOuterProject; } private static void SimplifyCaseStatements(ExpressionReplacement replacement) { var candidate = replacement.Current; if (candidate.ExpressionKind != DbExpressionKind.Case) { return; } var caseExpression = (DbCaseExpression)replacement.Current; // try simplifying predicates bool predicateSimplified = false; List rewrittenPredicates = new List (caseExpression.When.Count); foreach (var when in caseExpression.When) { DbExpression simplifiedPredicate; if (TrySimplifyPredicate(when, out simplifiedPredicate)) { rewrittenPredicates.Add(simplifiedPredicate); predicateSimplified = true; } else { rewrittenPredicates.Add(when); } } if (!predicateSimplified) { return; } replacement.Replacement = caseExpression.CommandTree.CreateCaseExpression( rewrittenPredicates, caseExpression.Then, caseExpression.Else); replacement.VisitReplacement = true; } private static bool TrySimplifyPredicate(DbExpression predicate, out DbExpression simplified) { simplified = null; if (predicate.ExpressionKind != DbExpressionKind.Case) { return false; } var caseExpression = (DbCaseExpression)predicate; if (caseExpression.Then.Count != 1 && caseExpression.Then[0].ExpressionKind == DbExpressionKind.Constant) { return false; } var then = (DbConstantExpression)caseExpression.Then[0]; if (!true.Equals(then.Value)) { return false; } if (caseExpression.Else != null) { if (caseExpression.Else.ExpressionKind != DbExpressionKind.Constant) { return false; } var when = (DbConstantExpression)caseExpression.Else; if (!false.Equals(when.Value)) { return false; } } simplified = caseExpression.When[0]; return true; } /// /// replacer used to simplify argument value in a new instance expression OuterNew from /// an expression of the form: /// /// outerProject(outerBinding(innerProject(innerBinding, innerNew)), outerProjection) /// /// The replacer collapses the outer project terms to point at the innerNew expression. /// Where possible, VarRef_outer.Property_outer is collapsed to VarRef_inner.Property. /// private class ProjectionCollapser { // the replacer context keeps track of member bindings for var refs and the expression // binding for the outer projection being remapped private Dictionarym_varRefMemberBindings; private DbExpressionBinding m_outerBinding; private bool m_doomed; internal ProjectionCollapser(Dictionary varRefMemberBindings, DbExpressionBinding outerBinding) { m_varRefMemberBindings = varRefMemberBindings; m_outerBinding = outerBinding; } // replacer delegate that identifies the Property(VarRef "Outer binding") pattern, // and remaps the property to the appropriate inner projection member internal void CollapseProjection(ExpressionReplacement replacement) { // check for a property of the outer projection binding (that can be remapped) if (replacement.Current.ExpressionKind == DbExpressionKind.Property) { var property = (DbPropertyExpression)replacement.Current; if (property.Instance.ExpressionKind == DbExpressionKind.VariableReference && IsOuterBindingVarRef((DbVariableReferenceExpression)property.Instance)) { replacement.VisitReplacement = false; replacement.Replacement = m_varRefMemberBindings[property.Property.Name]; } } else if (replacement.Current.ExpressionKind == DbExpressionKind.VariableReference) { // if we encounter an unsubstitutued var ref, give up... var varRef = (DbVariableReferenceExpression)replacement.Current; if (IsOuterBindingVarRef(varRef)) { m_doomed = true; } } } /// /// Heuristic check to make sure the var ref is the one we're supposed to be replacing. /// private bool IsOuterBindingVarRef(DbVariableReferenceExpression varRef) { return varRef.VariableName == m_outerBinding.VariableName; } ////// Returns a value indicating that the transformation has failed. /// internal bool IsDoomed { get { return m_doomed; } } } /* private abstract class DiscriminatorValueCollection { ////// Add a new discriminator value. Returns true if the value is unique. /// internal abstract bool TryAddDiscriminatorValue(object value); ////// Associate a discriminator value with the given type. Returns true if the value is known. /// internal abstract bool TryAddDiscriminatorValueAssignment(object value, EntityType entityType); ////// /// internal abstract bool TryAssignDefaultType(EntityType entityType); private class TypedDiscriminatorValueCollection{ private readonly TryConvert _convert; private readonly Func , T> _generateUniqueDiscriminator; private readonly HashSet _discriminatorValues; private readonly Dictionary _discriminatorAssignments; } private delegate bool TryConvert (object input, out T output); } * */ } } // 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
- path.cs
- StructuralObject.cs
- BoundColumn.cs
- BevelBitmapEffect.cs
- ValuePattern.cs
- HwndPanningFeedback.cs
- IdentityReference.cs
- ByteAnimation.cs
- InternalConfigConfigurationFactory.cs
- NativeRecognizer.cs
- ChildDocumentBlock.cs
- TableLayoutPanel.cs
- InstanceKey.cs
- TrackPoint.cs
- SqlServices.cs
- TreeNodeCollection.cs
- InternalConfigRoot.cs
- FrameSecurityDescriptor.cs
- DataGridHeaderBorder.cs
- ShapingWorkspace.cs
- SspiSecurityTokenParameters.cs
- ActivitySurrogate.cs
- EventToken.cs
- AsyncResult.cs
- DeclarationUpdate.cs
- FormsAuthenticationConfiguration.cs
- MulticastOption.cs
- DefaultTextStore.cs
- AQNBuilder.cs
- BinaryExpression.cs
- querybuilder.cs
- IItemContainerGenerator.cs
- TextRunCache.cs
- SafeNativeMemoryHandle.cs
- SyndicationSerializer.cs
- Stroke.cs
- configsystem.cs
- List.cs
- PieceNameHelper.cs
- ClientBuildManager.cs
- SqlDataSourceEnumerator.cs
- ContainerParaClient.cs
- LiteralTextParser.cs
- WinEventQueueItem.cs
- DataGridViewCellStyle.cs
- TriggerAction.cs
- BackStopAuthenticationModule.cs
- OperationCanceledException.cs
- AnimationException.cs
- XmlAttributeCollection.cs
- StrokeNodeData.cs
- Literal.cs
- HttpServerUtilityWrapper.cs
- DesignerActionHeaderItem.cs
- Range.cs
- ScriptIgnoreAttribute.cs
- ChangeConflicts.cs
- EdmRelationshipNavigationPropertyAttribute.cs
- StorageTypeMapping.cs
- XmlSchemaAppInfo.cs
- WindowsUpDown.cs
- CodeDomExtensionMethods.cs
- DataServiceQueryException.cs
- WebPartEditorApplyVerb.cs
- QilName.cs
- ControlBindingsCollection.cs
- _ConnectOverlappedAsyncResult.cs
- WindowsAltTab.cs
- ResXFileRef.cs
- mediaeventshelper.cs
- ExtendedPropertyCollection.cs
- TaskForm.cs
- ParamArrayAttribute.cs
- SystemResourceKey.cs
- HashHelper.cs
- TextParagraphCache.cs
- DataGridViewAccessibleObject.cs
- HtmlInputFile.cs
- HttpHeaderCollection.cs
- SlotInfo.cs
- ConnectionOrientedTransportChannelFactory.cs
- MemberRelationshipService.cs
- StrongNamePublicKeyBlob.cs
- LineSegment.cs
- SpotLight.cs
- SmtpSection.cs
- BasePropertyDescriptor.cs
- Menu.cs
- TrackBarRenderer.cs
- QilName.cs
- ImageFormatConverter.cs
- WebPartConnectionsCancelEventArgs.cs
- HMACSHA512.cs
- DrawListViewSubItemEventArgs.cs
- OleDbMetaDataFactory.cs
- CommandSet.cs
- RepeaterCommandEventArgs.cs
- SocketElement.cs
- DesigntimeLicenseContextSerializer.cs
- Calendar.cs