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
- BitmapMetadataEnumerator.cs
- FixedHyperLink.cs
- Ops.cs
- JsonSerializer.cs
- PeerToPeerException.cs
- MailBnfHelper.cs
- WSSecurityOneDotOneReceiveSecurityHeader.cs
- CellParaClient.cs
- RuleConditionDialog.cs
- PerformanceCounterManager.cs
- QueryOptionExpression.cs
- DetailsViewModeEventArgs.cs
- Transform3D.cs
- ImageCodecInfoPrivate.cs
- ParseNumbers.cs
- CompiledQuery.cs
- RootBrowserWindowProxy.cs
- Transform3DGroup.cs
- UIAgentAsyncParams.cs
- CopyEncoder.cs
- ScriptDescriptor.cs
- AdornerPresentationContext.cs
- QilInvoke.cs
- MenuItemStyleCollection.cs
- RepeatInfo.cs
- HttpBrowserCapabilitiesWrapper.cs
- ControlBindingsCollection.cs
- ModelPropertyCollectionImpl.cs
- DetailsViewModeEventArgs.cs
- ObjectFullSpanRewriter.cs
- XmlProcessingInstruction.cs
- Expression.cs
- ConfigurationException.cs
- EditingContext.cs
- InstanceData.cs
- XmlChildNodes.cs
- ManagedIStream.cs
- ExtenderProvidedPropertyAttribute.cs
- ObfuscationAttribute.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- InkCanvas.cs
- Equal.cs
- DescendantQuery.cs
- OleDbMetaDataFactory.cs
- WinFormsUtils.cs
- HttpModulesSection.cs
- SafeThemeHandle.cs
- Int16Storage.cs
- BitArray.cs
- DragEventArgs.cs
- PartialList.cs
- ExtendedProperty.cs
- PublisherIdentityPermission.cs
- InheritanceAttribute.cs
- TriggerCollection.cs
- TableLayoutSettings.cs
- PrincipalPermission.cs
- WebPartsPersonalizationAuthorization.cs
- ImageBrush.cs
- XmlLoader.cs
- SortableBindingList.cs
- ChildTable.cs
- bidPrivateBase.cs
- InkSerializer.cs
- EntityCodeGenerator.cs
- RelatedCurrencyManager.cs
- InplaceBitmapMetadataWriter.cs
- SmiXetterAccessMap.cs
- PersonalizationEntry.cs
- ImageMapEventArgs.cs
- LogSwitch.cs
- TimelineGroup.cs
- diagnosticsswitches.cs
- NavigationPropertyEmitter.cs
- SrgsRulesCollection.cs
- ValidatingReaderNodeData.cs
- StateMachineDesignerPaint.cs
- SyncMethodInvoker.cs
- PostBackTrigger.cs
- DeferrableContent.cs
- ObjectDataSourceEventArgs.cs
- StylusPointProperties.cs
- RequestQueryProcessor.cs
- LabelAutomationPeer.cs
- SrgsText.cs
- ContentDesigner.cs
- StandardBindingImporter.cs
- RawStylusInputReport.cs
- FormViewPageEventArgs.cs
- CodeSnippetTypeMember.cs
- TiffBitmapDecoder.cs
- XmlCharCheckingWriter.cs
- CharStorage.cs
- ResumeStoryboard.cs
- TargetConverter.cs
- XamlDesignerSerializationManager.cs
- GrammarBuilderRuleRef.cs
- DataGridBoolColumn.cs
- DataGridTableCollection.cs
- CryptoHelper.cs