Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / ndp / fx / src / DataEntity / System / Data / Common / CommandTrees / Internal / ViewSimplifier.cs / 2 / 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
- EntityConnectionStringBuilder.cs
- Effect.cs
- BackEase.cs
- ResourceAttributes.cs
- SQLDoubleStorage.cs
- MessageQueuePermission.cs
- ViewDesigner.cs
- SRef.cs
- PeerName.cs
- VerificationAttribute.cs
- SqlCacheDependencySection.cs
- XmlElement.cs
- OrderedParallelQuery.cs
- XmlDigitalSignatureProcessor.cs
- HostProtectionPermission.cs
- OdbcHandle.cs
- RtfNavigator.cs
- Context.cs
- _SingleItemRequestCache.cs
- DBPropSet.cs
- regiisutil.cs
- SoapFault.cs
- AlignmentYValidation.cs
- MenuCommand.cs
- ToolStripKeyboardHandlingService.cs
- BulletedList.cs
- ServiceBusyException.cs
- StringStorage.cs
- ResourceManager.cs
- FunctionQuery.cs
- UnicastIPAddressInformationCollection.cs
- WpfSharedBamlSchemaContext.cs
- PropertyDescriptorGridEntry.cs
- BooleanAnimationBase.cs
- CodeExpressionCollection.cs
- Number.cs
- ChtmlTextWriter.cs
- ConnectionStringsExpressionBuilder.cs
- QilNode.cs
- FixedSOMTableRow.cs
- MultipartIdentifier.cs
- ViewStateException.cs
- PropertyCondition.cs
- DataGridAutoGeneratingColumnEventArgs.cs
- Matrix3DValueSerializer.cs
- HtmlToClrEventProxy.cs
- PopOutPanel.cs
- FreezableDefaultValueFactory.cs
- WrappedKeySecurityTokenParameters.cs
- NamedObject.cs
- SchemaSetCompiler.cs
- TextEffectCollection.cs
- FixedSOMImage.cs
- WebPartDisplayModeCancelEventArgs.cs
- JsonServiceDocumentSerializer.cs
- DetailsViewPageEventArgs.cs
- Keyboard.cs
- SamlAttributeStatement.cs
- GridViewEditEventArgs.cs
- WebPartDisplayMode.cs
- Base64WriteStateInfo.cs
- ServiceParser.cs
- InvokeMethod.cs
- TextSchema.cs
- AnimationLayer.cs
- MetadataPropertyAttribute.cs
- HtmlElementErrorEventArgs.cs
- MediaPlayerState.cs
- AttributeCollection.cs
- OpenFileDialog.cs
- HttpListenerContext.cs
- FillBehavior.cs
- TextProviderWrapper.cs
- QueryConverter.cs
- OAVariantLib.cs
- ClrPerspective.cs
- CurrentTimeZone.cs
- CalendarButtonAutomationPeer.cs
- SqlColumnizer.cs
- TileBrush.cs
- CatalogPartCollection.cs
- AgileSafeNativeMemoryHandle.cs
- CommandField.cs
- SemaphoreFullException.cs
- TextTreeRootTextBlock.cs
- Marshal.cs
- CompressionTransform.cs
- CookieHandler.cs
- MexServiceChannelBuilder.cs
- FileUtil.cs
- SqlDependencyUtils.cs
- safex509handles.cs
- InteropBitmapSource.cs
- Wrapper.cs
- WindowsProgressbar.cs
- EncryptedData.cs
- StrongNamePublicKeyBlob.cs
- DataView.cs
- AttributedMetaModel.cs
- ServiceDefaults.cs