Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlLiftWhereClauses.cs / 1305376 / SqlLiftWhereClauses.cs
using System; using System.Collections.Generic; using System.Text; using System.Data.Linq.Mapping; using System.Data.Linq.Provider; namespace System.Data.Linq.SqlClient { ////// Hoist WHERE clauses as close to the root as possible. /// class SqlLiftWhereClauses { internal static SqlNode Lift(SqlNode node, TypeSystemProvider typeProvider, MetaModel model) { return new Lifter(typeProvider, model).Visit(node); } class Lifter : SqlVisitor { private class Scope { internal Scope Parent; internal SqlExpression Where; internal Scope(SqlExpression where, Scope parent) { this.Where = where; this.Parent = parent; } }; Scope current; SqlFactory sql; SqlAggregateChecker aggregateChecker; SqlRowNumberChecker rowNumberChecker; internal Lifter(TypeSystemProvider typeProvider, MetaModel model) { this.sql = new SqlFactory(typeProvider, model); this.aggregateChecker = new SqlAggregateChecker(); this.rowNumberChecker = new SqlRowNumberChecker(); } internal override SqlSelect VisitSelect(SqlSelect select) { Scope save = this.current; this.current = new Scope(select.Where, this.current); SqlSelect result = base.VisitSelect(select); bool stopHoisting = select.IsDistinct || select.GroupBy.Count > 0 || this.aggregateChecker.HasAggregates(select) || select.Top != null || this.rowNumberChecker.HasRowNumber(select); // Shift as much of the current WHERE to the parent as possible. if (this.current != null) { if (this.current.Parent != null && !stopHoisting) { this.current.Parent.Where = sql.AndAccumulate(this.current.Parent.Where, this.current.Where); this.current.Where = null; } select.Where = this.current.Where; } this.current = save; return result; } internal override SqlNode VisitUnion(SqlUnion su) { Scope save = this.current; this.current = null; SqlNode result = base.VisitUnion(su); this.current = save; return result; } internal override SqlSource VisitJoin(SqlJoin join) { // block where clauses from being lifted out of the cardinality-dependent // side of an outer join. Scope save = this.current; try { switch (join.JoinType) { case SqlJoinType.Cross: case SqlJoinType.CrossApply: case SqlJoinType.Inner: return base.VisitJoin(join); case SqlJoinType.LeftOuter: case SqlJoinType.OuterApply: { join.Left = this.VisitSource(join.Left); this.current = null; join.Right = this.VisitSource(join.Right); join.Condition = this.VisitExpression(join.Condition); return join; } default: this.current = null; return base.VisitJoin(join); } } finally { this.current = save; } } internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { // block where clauses from being lifted out of a sub-query Scope save = this.current; this.current = null; SqlExpression result = base.VisitSubSelect(ss); this.current = save; return result; } internal override SqlExpression VisitClientQuery(SqlClientQuery cq) { // block where clauses from being lifted out of a client-materialized sub-query Scope save = this.current; this.current = null; SqlExpression result = base.VisitClientQuery(cq); this.current = save; return result; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved. using System; using System.Collections.Generic; using System.Text; using System.Data.Linq.Mapping; using System.Data.Linq.Provider; namespace System.Data.Linq.SqlClient { ////// Hoist WHERE clauses as close to the root as possible. /// class SqlLiftWhereClauses { internal static SqlNode Lift(SqlNode node, TypeSystemProvider typeProvider, MetaModel model) { return new Lifter(typeProvider, model).Visit(node); } class Lifter : SqlVisitor { private class Scope { internal Scope Parent; internal SqlExpression Where; internal Scope(SqlExpression where, Scope parent) { this.Where = where; this.Parent = parent; } }; Scope current; SqlFactory sql; SqlAggregateChecker aggregateChecker; SqlRowNumberChecker rowNumberChecker; internal Lifter(TypeSystemProvider typeProvider, MetaModel model) { this.sql = new SqlFactory(typeProvider, model); this.aggregateChecker = new SqlAggregateChecker(); this.rowNumberChecker = new SqlRowNumberChecker(); } internal override SqlSelect VisitSelect(SqlSelect select) { Scope save = this.current; this.current = new Scope(select.Where, this.current); SqlSelect result = base.VisitSelect(select); bool stopHoisting = select.IsDistinct || select.GroupBy.Count > 0 || this.aggregateChecker.HasAggregates(select) || select.Top != null || this.rowNumberChecker.HasRowNumber(select); // Shift as much of the current WHERE to the parent as possible. if (this.current != null) { if (this.current.Parent != null && !stopHoisting) { this.current.Parent.Where = sql.AndAccumulate(this.current.Parent.Where, this.current.Where); this.current.Where = null; } select.Where = this.current.Where; } this.current = save; return result; } internal override SqlNode VisitUnion(SqlUnion su) { Scope save = this.current; this.current = null; SqlNode result = base.VisitUnion(su); this.current = save; return result; } internal override SqlSource VisitJoin(SqlJoin join) { // block where clauses from being lifted out of the cardinality-dependent // side of an outer join. Scope save = this.current; try { switch (join.JoinType) { case SqlJoinType.Cross: case SqlJoinType.CrossApply: case SqlJoinType.Inner: return base.VisitJoin(join); case SqlJoinType.LeftOuter: case SqlJoinType.OuterApply: { join.Left = this.VisitSource(join.Left); this.current = null; join.Right = this.VisitSource(join.Right); join.Condition = this.VisitExpression(join.Condition); return join; } default: this.current = null; return base.VisitJoin(join); } } finally { this.current = save; } } internal override SqlExpression VisitSubSelect(SqlSubSelect ss) { // block where clauses from being lifted out of a sub-query Scope save = this.current; this.current = null; SqlExpression result = base.VisitSubSelect(ss); this.current = save; return result; } internal override SqlExpression VisitClientQuery(SqlClientQuery cq) { // block where clauses from being lifted out of a client-materialized sub-query Scope save = this.current; this.current = null; SqlExpression result = base.VisitClientQuery(cq); this.current = save; return result; } } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- SafeEventLogWriteHandle.cs
- IntranetCredentialPolicy.cs
- XmlWriterTraceListener.cs
- TimerEventSubscription.cs
- CurrencyManager.cs
- TreeNodeEventArgs.cs
- CanonicalXml.cs
- TextEditorParagraphs.cs
- XmlBinaryReader.cs
- ConnectionConsumerAttribute.cs
- IntellisenseTextBox.cs
- CorePropertiesFilter.cs
- RoleGroup.cs
- CursorConverter.cs
- SqlVersion.cs
- FragmentQuery.cs
- UrlPropertyAttribute.cs
- NetworkInformationException.cs
- ExclusiveNamedPipeTransportManager.cs
- XsltContext.cs
- GacUtil.cs
- SweepDirectionValidation.cs
- VisualStyleTypesAndProperties.cs
- ConfigurationStrings.cs
- PeerPresenceInfo.cs
- DiscoveryVersion.cs
- AssemblyAttributes.cs
- PersonalizableTypeEntry.cs
- ByValueEqualityComparer.cs
- ThreadAbortException.cs
- IProducerConsumerCollection.cs
- PointIndependentAnimationStorage.cs
- XmlSerializerVersionAttribute.cs
- HebrewNumber.cs
- DataPagerFieldCollection.cs
- NativeCppClassAttribute.cs
- SecurityTokenValidationException.cs
- EntityAdapter.cs
- BlurBitmapEffect.cs
- Model3DGroup.cs
- TemplateControlParser.cs
- TypeUsageBuilder.cs
- TagPrefixCollection.cs
- TypefaceCollection.cs
- FormatterServices.cs
- TreeChangeInfo.cs
- RepeaterItemCollection.cs
- SrgsGrammar.cs
- unitconverter.cs
- OptimalTextSource.cs
- InputLanguageManager.cs
- ConnectorSelectionGlyph.cs
- SqlBuilder.cs
- DialogResultConverter.cs
- CookieParameter.cs
- ExtensionElementCollection.cs
- HttpModuleAction.cs
- RankException.cs
- WindowsToolbarItemAsMenuItem.cs
- RenderingEventArgs.cs
- OperatingSystem.cs
- NativeMethods.cs
- SQLDecimal.cs
- TableCellAutomationPeer.cs
- Type.cs
- cache.cs
- Geometry.cs
- KeyGesture.cs
- ExeContext.cs
- ErrorCodes.cs
- ClockController.cs
- WebBrowserBase.cs
- NonVisualControlAttribute.cs
- BlurEffect.cs
- XmlNodeComparer.cs
- ConstrainedDataObject.cs
- SystemException.cs
- EventsTab.cs
- OdbcDataAdapter.cs
- DomNameTable.cs
- XXXOnTypeBuilderInstantiation.cs
- NonBatchDirectoryCompiler.cs
- ImplicitInputBrush.cs
- BevelBitmapEffect.cs
- UnsafeNativeMethods.cs
- XmlHelper.cs
- TextUtf8RawTextWriter.cs
- ContractBase.cs
- HashMembershipCondition.cs
- CfgRule.cs
- assertwrapper.cs
- SiteOfOriginPart.cs
- WebPartDescription.cs
- DbConnectionStringCommon.cs
- CacheVirtualItemsEvent.cs
- Operator.cs
- Calendar.cs
- ApplicationServiceHelper.cs
- Int32RectValueSerializer.cs
- BridgeDataRecord.cs