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
- InvalidComObjectException.cs
- AddingNewEventArgs.cs
- XmlImplementation.cs
- ColorComboBox.cs
- ObjectNavigationPropertyMapping.cs
- SafeFileMappingHandle.cs
- DbConnectionPool.cs
- XmlChildNodes.cs
- AssemblyBuilder.cs
- DateTimeOffset.cs
- HttpCachePolicy.cs
- IItemProperties.cs
- XmlAttributeCache.cs
- Font.cs
- Messages.cs
- Page.cs
- XmlSchema.cs
- CounterCreationDataCollection.cs
- CmsUtils.cs
- RuleSettings.cs
- selecteditemcollection.cs
- HtmlControlPersistable.cs
- TraceUtils.cs
- securitycriticaldataformultiplegetandset.cs
- ActiveXContainer.cs
- XmlNamespaceMappingCollection.cs
- IteratorDescriptor.cs
- EventLogLink.cs
- Error.cs
- WebPartVerbCollection.cs
- StandardOleMarshalObject.cs
- ThreadAbortException.cs
- UnsignedPublishLicense.cs
- IndexerNameAttribute.cs
- ResourcesChangeInfo.cs
- Vector3DAnimationBase.cs
- WebConfigurationHostFileChange.cs
- GradientBrush.cs
- ObjectViewEntityCollectionData.cs
- CharEntityEncoderFallback.cs
- WebPartDisplayModeEventArgs.cs
- NetCodeGroup.cs
- AppSettingsSection.cs
- ProtocolProfile.cs
- ClusterSafeNativeMethods.cs
- SQLSingle.cs
- SQLRoleProvider.cs
- BookmarkManager.cs
- StylusPointPropertyInfoDefaults.cs
- SimpleBitVector32.cs
- WebGetAttribute.cs
- RegistrationServices.cs
- StyleCollection.cs
- PeerNodeTraceRecord.cs
- MediaContext.cs
- XsdDuration.cs
- PermissionSetEnumerator.cs
- DataTransferEventArgs.cs
- ProcessThread.cs
- SqlException.cs
- RedBlackList.cs
- DataPagerFieldCollection.cs
- ThrowHelper.cs
- FormatException.cs
- CacheChildrenQuery.cs
- WindowsNonControl.cs
- EntityDataSourceDesigner.cs
- ToolStripPanel.cs
- CatalogPartCollection.cs
- FrameworkElementFactory.cs
- UnsupportedPolicyOptionsException.cs
- ResolvedKeyFrameEntry.cs
- XmlCodeExporter.cs
- ReadOnlyHierarchicalDataSource.cs
- UserControl.cs
- CompositeControlDesigner.cs
- RsaSecurityTokenAuthenticator.cs
- GPPOINT.cs
- Classification.cs
- TraceListeners.cs
- DataGridViewSelectedCellCollection.cs
- ObjectListItemCollection.cs
- xsdvalidator.cs
- PhonemeConverter.cs
- basenumberconverter.cs
- EntityDataSourceWizardForm.cs
- CodeNamespaceImport.cs
- SapiRecoInterop.cs
- DataColumnPropertyDescriptor.cs
- CodeRemoveEventStatement.cs
- StringUtil.cs
- NotifyInputEventArgs.cs
- RequestCache.cs
- Crypto.cs
- WinFormsSpinner.cs
- DllHostInitializer.cs
- DataSvcMapFile.cs
- sqlpipe.cs
- RoutedPropertyChangedEventArgs.cs
- DictionaryKeyPropertyAttribute.cs