Code:
/ Dotnetfx_Win7_3.5.1 / Dotnetfx_Win7_3.5.1 / 3.5.1 / DEVDIV / depot / DevDiv / releases / Orcas / NetFXw7 / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlColumnizer.cs / 1 / SqlColumnizer.cs
using System;
using System.Collections.Generic;
using System.Linq.Expressions;
using System.Reflection;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data.Linq.Provider;
using System.Linq;
using System.Data.Linq.SqlClient;
using System.Diagnostics.CodeAnalysis;
namespace System.Data.Linq.SqlClient {
// partions select expressions and common subexpressions into scalar and non-scalar pieces by
// wrapping scalar pieces floating column nodes.
internal class SqlColumnizer {
ColumnNominator nominator;
ColumnDeclarer declarer;
internal SqlColumnizer(Func fnCanBeColumn) {
this.nominator = new ColumnNominator(fnCanBeColumn);
this.declarer = new ColumnDeclarer();
}
internal SqlExpression ColumnizeSelection(SqlExpression selection) {
return this.declarer.Declare(selection, this.nominator.Nominate(selection));
}
class ColumnDeclarer : SqlVisitor {
HashSet candidates;
internal ColumnDeclarer() {
}
internal SqlExpression Declare(SqlExpression expression, HashSet candidates) {
this.candidates = candidates;
return (SqlExpression)this.Visit(expression);
}
internal override SqlNode Visit(SqlNode node) {
SqlExpression expr = node as SqlExpression;
if (expr != null) {
if (this.candidates.Contains(expr)) {
if (expr.NodeType == SqlNodeType.Column ||
expr.NodeType == SqlNodeType.ColumnRef) {
return expr;
}
else {
return new SqlColumn(expr.ClrType, expr.SqlType, null, null, expr, expr.SourceExpression);
}
}
}
return base.Visit(node);
}
}
class ColumnNominator : SqlVisitor {
bool isBlocked;
HashSet candidates;
Func fnCanBeColumn;
internal ColumnNominator(Func fnCanBeColumn) {
this.fnCanBeColumn = fnCanBeColumn;
}
internal HashSet Nominate(SqlExpression expression) {
this.candidates = new HashSet();
this.isBlocked = false;
this.Visit(expression);
return this.candidates;
}
internal override SqlNode Visit(SqlNode node) {
SqlExpression expression = node as SqlExpression;
if (expression != null) {
bool saveIsBlocked = this.isBlocked;
this.isBlocked = false;
if (CanRecurseColumnize(expression)) {
base.Visit(expression);
}
if (!this.isBlocked) {
if (!IsClientOnly(expression)
&& expression.NodeType != SqlNodeType.Column
&& expression.SqlType.CanBeColumn
&& (this.fnCanBeColumn == null || this.fnCanBeColumn(expression))
) {
this.candidates.Add(expression);
}
else {
this.isBlocked = true;
}
}
this.isBlocked |= saveIsBlocked;
}
return node;
}
internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) {
c.Expression = this.VisitExpression(c.Expression);
for (int i = 0, n = c.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
}
return c;
}
internal override SqlExpression VisitTypeCase(SqlTypeCase tc) {
tc.Discriminator = this.VisitExpression(tc.Discriminator);
for (int i = 0, n = tc.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
tc.Whens[i].TypeBinding = this.VisitExpression(tc.Whens[i].TypeBinding);
}
return tc;
}
internal override SqlExpression VisitClientCase(SqlClientCase c) {
c.Expression = this.VisitExpression(c.Expression);
for (int i = 0, n = c.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
}
return c;
}
private static bool CanRecurseColumnize(SqlExpression expr) {
switch (expr.NodeType) {
case SqlNodeType.AliasRef:
case SqlNodeType.ColumnRef:
case SqlNodeType.Column:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.ScalarSubSelect:
case SqlNodeType.Exists:
case SqlNodeType.ClientQuery:
case SqlNodeType.SharedExpressionRef:
case SqlNodeType.Link:
case SqlNodeType.Nop:
case SqlNodeType.Value:
case SqlNodeType.Select:
return false;
default:
return true;
}
}
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification="These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
private static bool IsClientOnly(SqlExpression expr) {
switch (expr.NodeType) {
case SqlNodeType.ClientCase:
case SqlNodeType.TypeCase:
case SqlNodeType.ClientArray:
case SqlNodeType.Grouping:
case SqlNodeType.DiscriminatedType:
case SqlNodeType.SharedExpression:
case SqlNodeType.SimpleExpression:
case SqlNodeType.AliasRef:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.ClientQuery:
case SqlNodeType.SharedExpressionRef:
case SqlNodeType.Link:
case SqlNodeType.Nop:
return true;
case SqlNodeType.OuterJoinedValue:
return IsClientOnly(((SqlUnary)expr).Operand);
default:
return false;
}
}
}
}
}
// 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.Linq.Expressions;
using System.Reflection;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data.Linq.Provider;
using System.Linq;
using System.Data.Linq.SqlClient;
using System.Diagnostics.CodeAnalysis;
namespace System.Data.Linq.SqlClient {
// partions select expressions and common subexpressions into scalar and non-scalar pieces by
// wrapping scalar pieces floating column nodes.
internal class SqlColumnizer {
ColumnNominator nominator;
ColumnDeclarer declarer;
internal SqlColumnizer(Func fnCanBeColumn) {
this.nominator = new ColumnNominator(fnCanBeColumn);
this.declarer = new ColumnDeclarer();
}
internal SqlExpression ColumnizeSelection(SqlExpression selection) {
return this.declarer.Declare(selection, this.nominator.Nominate(selection));
}
class ColumnDeclarer : SqlVisitor {
HashSet candidates;
internal ColumnDeclarer() {
}
internal SqlExpression Declare(SqlExpression expression, HashSet candidates) {
this.candidates = candidates;
return (SqlExpression)this.Visit(expression);
}
internal override SqlNode Visit(SqlNode node) {
SqlExpression expr = node as SqlExpression;
if (expr != null) {
if (this.candidates.Contains(expr)) {
if (expr.NodeType == SqlNodeType.Column ||
expr.NodeType == SqlNodeType.ColumnRef) {
return expr;
}
else {
return new SqlColumn(expr.ClrType, expr.SqlType, null, null, expr, expr.SourceExpression);
}
}
}
return base.Visit(node);
}
}
class ColumnNominator : SqlVisitor {
bool isBlocked;
HashSet candidates;
Func fnCanBeColumn;
internal ColumnNominator(Func fnCanBeColumn) {
this.fnCanBeColumn = fnCanBeColumn;
}
internal HashSet Nominate(SqlExpression expression) {
this.candidates = new HashSet();
this.isBlocked = false;
this.Visit(expression);
return this.candidates;
}
internal override SqlNode Visit(SqlNode node) {
SqlExpression expression = node as SqlExpression;
if (expression != null) {
bool saveIsBlocked = this.isBlocked;
this.isBlocked = false;
if (CanRecurseColumnize(expression)) {
base.Visit(expression);
}
if (!this.isBlocked) {
if (!IsClientOnly(expression)
&& expression.NodeType != SqlNodeType.Column
&& expression.SqlType.CanBeColumn
&& (this.fnCanBeColumn == null || this.fnCanBeColumn(expression))
) {
this.candidates.Add(expression);
}
else {
this.isBlocked = true;
}
}
this.isBlocked |= saveIsBlocked;
}
return node;
}
internal override SqlExpression VisitSimpleCase(SqlSimpleCase c) {
c.Expression = this.VisitExpression(c.Expression);
for (int i = 0, n = c.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
}
return c;
}
internal override SqlExpression VisitTypeCase(SqlTypeCase tc) {
tc.Discriminator = this.VisitExpression(tc.Discriminator);
for (int i = 0, n = tc.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
tc.Whens[i].TypeBinding = this.VisitExpression(tc.Whens[i].TypeBinding);
}
return tc;
}
internal override SqlExpression VisitClientCase(SqlClientCase c) {
c.Expression = this.VisitExpression(c.Expression);
for (int i = 0, n = c.Whens.Count; i < n; i++) {
// Don't walk down the match side. This can't be a column.
c.Whens[i].Value = this.VisitExpression(c.Whens[i].Value);
}
return c;
}
private static bool CanRecurseColumnize(SqlExpression expr) {
switch (expr.NodeType) {
case SqlNodeType.AliasRef:
case SqlNodeType.ColumnRef:
case SqlNodeType.Column:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.ScalarSubSelect:
case SqlNodeType.Exists:
case SqlNodeType.ClientQuery:
case SqlNodeType.SharedExpressionRef:
case SqlNodeType.Link:
case SqlNodeType.Nop:
case SqlNodeType.Value:
case SqlNodeType.Select:
return false;
default:
return true;
}
}
[SuppressMessage("Microsoft.Maintainability", "CA1502:AvoidExcessiveComplexity", Justification="These issues are related to our use of if-then and case statements for node types, which adds to the complexity count however when reviewed they are easy to navigate and understand.")]
private static bool IsClientOnly(SqlExpression expr) {
switch (expr.NodeType) {
case SqlNodeType.ClientCase:
case SqlNodeType.TypeCase:
case SqlNodeType.ClientArray:
case SqlNodeType.Grouping:
case SqlNodeType.DiscriminatedType:
case SqlNodeType.SharedExpression:
case SqlNodeType.SimpleExpression:
case SqlNodeType.AliasRef:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.ClientQuery:
case SqlNodeType.SharedExpressionRef:
case SqlNodeType.Link:
case SqlNodeType.Nop:
return true;
case SqlNodeType.OuterJoinedValue:
return IsClientOnly(((SqlUnary)expr).Operand);
default:
return false;
}
}
}
}
}
// 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
- SecurityTokenValidationException.cs
- XmlLanguageConverter.cs
- InvokeMethodActivity.cs
- DataGridViewRowStateChangedEventArgs.cs
- UniformGrid.cs
- RecognizedWordUnit.cs
- ButtonChrome.cs
- ExpressionBuilderContext.cs
- WebConfigurationManager.cs
- XmlDownloadManager.cs
- Stopwatch.cs
- FreezableDefaultValueFactory.cs
- FileUtil.cs
- NamespaceList.cs
- PackageRelationshipCollection.cs
- DbDataAdapter.cs
- StringAttributeCollection.cs
- GroupBox.cs
- UrlAuthorizationModule.cs
- XmlSchemaObjectCollection.cs
- DependencySource.cs
- exports.cs
- EntityDataSourceContainerNameItem.cs
- PageParser.cs
- TransformCollection.cs
- TrackBarRenderer.cs
- PtsPage.cs
- ControlBuilderAttribute.cs
- MailHeaderInfo.cs
- MulticastOption.cs
- HttpConfigurationSystem.cs
- Win32Interop.cs
- BitmapEffectDrawingContextState.cs
- X509ServiceCertificateAuthentication.cs
- MetadataItemEmitter.cs
- HttpValueCollection.cs
- CfgParser.cs
- ZipIOLocalFileHeader.cs
- LiteralTextContainerControlBuilder.cs
- New.cs
- TextBoxAutomationPeer.cs
- AuthenticationConfig.cs
- XmlDataSourceNodeDescriptor.cs
- JsonCollectionDataContract.cs
- CollectionContainer.cs
- ErrorHandlingReceiver.cs
- EmbeddedMailObject.cs
- DataGridCaption.cs
- SQLByte.cs
- PeerCollaborationPermission.cs
- ToolStripSplitButton.cs
- ItemContainerPattern.cs
- TextElementCollection.cs
- GridEntryCollection.cs
- EventSinkActivity.cs
- EmbeddedObject.cs
- OleDbWrapper.cs
- ConfigXmlComment.cs
- PasswordBox.cs
- InsufficientExecutionStackException.cs
- UnsafeNativeMethods.cs
- DataSourceSelectArguments.cs
- TreeIterator.cs
- FormViewRow.cs
- MissingManifestResourceException.cs
- TextEditor.cs
- CultureSpecificCharacterBufferRange.cs
- nulltextcontainer.cs
- Pointer.cs
- TemplateControlParser.cs
- NameValuePair.cs
- SerialPinChanges.cs
- CopyOnWriteList.cs
- DropTarget.cs
- FormsAuthenticationConfiguration.cs
- EditCommandColumn.cs
- ButtonPopupAdapter.cs
- PolyLineSegment.cs
- ImageEditor.cs
- TemplatePropertyEntry.cs
- HMACRIPEMD160.cs
- Console.cs
- Normalizer.cs
- CodeTypeParameterCollection.cs
- DocumentReference.cs
- TripleDES.cs
- TableLayoutColumnStyleCollection.cs
- Console.cs
- SourceLineInfo.cs
- WebPartEventArgs.cs
- TextBox.cs
- XmlCharType.cs
- TextContainerHelper.cs
- FusionWrap.cs
- __Filters.cs
- PropertyEmitterBase.cs
- InvokePattern.cs
- HierarchicalDataBoundControl.cs
- LineSegment.cs
- GenericWebPart.cs