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
- Boolean.cs
- ExecutionEngineException.cs
- AutomationAttributeInfo.cs
- TimeZone.cs
- DesignTimeSiteMapProvider.cs
- OutputCacheSettingsSection.cs
- EmptyStringExpandableObjectConverter.cs
- TableCellCollection.cs
- FormatConvertedBitmap.cs
- ViewValidator.cs
- PrintDialog.cs
- ProcessModelInfo.cs
- Track.cs
- SetStoryboardSpeedRatio.cs
- StringBlob.cs
- DataGridViewDataErrorEventArgs.cs
- BitmapCodecInfo.cs
- NotFiniteNumberException.cs
- DoubleLink.cs
- DataGridViewCellParsingEventArgs.cs
- PowerModeChangedEventArgs.cs
- PackagingUtilities.cs
- KeyValueConfigurationCollection.cs
- StaticTextPointer.cs
- LineSegment.cs
- OletxDependentTransaction.cs
- _HeaderInfoTable.cs
- ReadOnlyDataSourceView.cs
- SecurityListenerSettingsLifetimeManager.cs
- ValidatorAttribute.cs
- DataServiceContext.cs
- CommandHelper.cs
- ClientEventManager.cs
- StringBuilder.cs
- EntitySqlQueryState.cs
- NewExpression.cs
- ListViewUpdateEventArgs.cs
- ExecutionProperties.cs
- SystemGatewayIPAddressInformation.cs
- recordstate.cs
- CqlLexerHelpers.cs
- FloatSumAggregationOperator.cs
- XmlAnyElementAttributes.cs
- HtmlInputPassword.cs
- HttpWebRequest.cs
- UserControlBuildProvider.cs
- Html32TextWriter.cs
- UrlAuthorizationModule.cs
- TableLayoutCellPaintEventArgs.cs
- QueryCreatedEventArgs.cs
- WebExceptionStatus.cs
- QueryRelOp.cs
- SurrogateDataContract.cs
- HttpRuntimeSection.cs
- DataGridRowClipboardEventArgs.cs
- DataGridColumn.cs
- XsltException.cs
- InfocardExtendedInformationEntry.cs
- HttpInputStream.cs
- TemplatedAdorner.cs
- ServiceModelExtensionCollectionElement.cs
- XmlBoundElement.cs
- Codec.cs
- SearchForVirtualItemEventArgs.cs
- ImageBrush.cs
- RangeBaseAutomationPeer.cs
- DeleteMemberBinder.cs
- DrawListViewColumnHeaderEventArgs.cs
- StringCollection.cs
- FixedFindEngine.cs
- TreeNodeBindingDepthConverter.cs
- DataSourceHelper.cs
- WpfPayload.cs
- InternalBase.cs
- WebPartVerbCollection.cs
- TemplateBuilder.cs
- FieldBuilder.cs
- Selection.cs
- CodeIdentifiers.cs
- BooleanStorage.cs
- DataGridViewAdvancedBorderStyle.cs
- ModifyActivitiesPropertyDescriptor.cs
- KerberosRequestorSecurityTokenAuthenticator.cs
- UriWriter.cs
- OverflowException.cs
- KeyValueInternalCollection.cs
- Policy.cs
- Encoding.cs
- FirstMatchCodeGroup.cs
- TypeDefinition.cs
- ObjectParameterCollection.cs
- ETagAttribute.cs
- CompoundFileIOPermission.cs
- AnonymousIdentificationSection.cs
- XmlSchemaValidationException.cs
- TemplateXamlParser.cs
- XsltException.cs
- TriggerCollection.cs
- TypeDependencyAttribute.cs
- PageContent.cs