Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / TypeSource.cs / 1305376 / TypeSource.cs
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using System.Linq;
using System.Reflection;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data.Linq.Provider;
using System.Diagnostics.CodeAnalysis;
namespace System.Data.Linq.SqlClient {
///
/// Method used for dealing with dynamic types. The ClrType of SqlNode is the
/// statically known type originating in the source expression tree. For methods
/// like GetType(), we need to know the dynamic type that will be constructed.
///
internal static class TypeSource {
private class Visitor : SqlVisitor {
class UnwrapStack {
public UnwrapStack(UnwrapStack last, bool unwrap) {
Last = last;
Unwrap = unwrap;
}
public UnwrapStack Last { get; private set; }
public bool Unwrap { get; private set; }
}
UnwrapStack UnwrapSequences;
internal SqlExpression sourceExpression;
internal Type sourceType;
[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.")]
internal override SqlNode Visit(SqlNode node) {
if (node == null)
return null;
sourceExpression = node as SqlExpression;
if (sourceExpression != null) {
Type type = sourceExpression.ClrType;
UnwrapStack unwrap = this.UnwrapSequences;
while (unwrap != null) {
if (unwrap.Unwrap) {
type = TypeSystem.GetElementType(type);
}
unwrap = unwrap.Last;
}
sourceType = type;
}
if (sourceType != null && TypeSystem.GetNonNullableType(sourceType).IsValueType) {
return node; // Value types can't also have a dynamic type.
}
if (sourceType != null && TypeSystem.HasIEnumerable(sourceType)) {
return node; // Sequences can't be polymorphic.
}
switch (node.NodeType) {
case SqlNodeType.ScalarSubSelect:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.SearchedCase:
case SqlNodeType.ClientCase:
case SqlNodeType.SimpleCase:
case SqlNodeType.Member:
case SqlNodeType.DiscriminatedType:
case SqlNodeType.New:
case SqlNodeType.FunctionCall:
case SqlNodeType.MethodCall:
case SqlNodeType.Convert: // Object identity does not survive convert. It does survive Cast.
// Dig no further.
return node;
case SqlNodeType.TypeCase:
sourceType = ((SqlTypeCase)node).RowType.Type;
return node;
case SqlNodeType.Link:
sourceType = ((SqlLink)node).RowType.Type;
return node;
case SqlNodeType.Table:
sourceType = ((SqlTable)node).RowType.Type;
return node;
case SqlNodeType.Value:
SqlValue val = (SqlValue)node;
if (val.Value != null) {
// In some cases the ClrType of a Value node may
// differ from the actual runtime type of the value.
// Therefore, we ensure here that the correct type is set.
sourceType = val.Value.GetType();
}
return node;
}
return base.Visit(node);
}
internal override SqlSelect VisitSelect(SqlSelect select) {
/*
* We're travelling through of something like:
*
* SELECT
* FROM
*
* Inside the expression there may be a reference to that
* represents the dynamic type that we're trying to discover.
*
* In this case, the type relationship between AliasRef and Alias is
* T to IEnumerable.
*
* We need to remember to 'unpivot' the type of IEnumerable to
* get the correct dynamic type.
*
* Since SELECTs may be nested, we use a stack of pivots.
*
*/
this.UnwrapSequences = new UnwrapStack(this.UnwrapSequences, true);
VisitExpression(select.Selection);
this.UnwrapSequences = this.UnwrapSequences.Last;
return select;
}
internal override SqlExpression VisitAliasRef(SqlAliasRef aref) {
if (this.UnwrapSequences != null && this.UnwrapSequences.Unwrap) {
this.UnwrapSequences = new UnwrapStack(this.UnwrapSequences, false);
this.VisitAlias(aref.Alias);
this.UnwrapSequences = this.UnwrapSequences.Last;
} else {
this.VisitAlias(aref.Alias);
}
return aref;
}
internal override SqlExpression VisitColumnRef(SqlColumnRef cref) {
this.VisitColumn(cref.Column); // Travel through column references
return cref;
}
}
///
/// Get a MetaType that represents the dynamic type of the given node.
///
internal static MetaType GetSourceMetaType(SqlNode node, MetaModel model) {
Visitor v = new Visitor();
v.Visit(node);
Type type = v.sourceType;
type = TypeSystem.GetNonNullableType(type); // Emulate CLR's behavior: strip nullability from type.
return model.GetMetaType(type);
}
///
/// Retrieve the expression that will represent the _dynamic_ type of the
/// given expression. This is either a SqlDiscriminatedType or a SqlValue
/// of type Type.
///
internal static SqlExpression GetTypeSource(SqlExpression expr) {
Visitor v = new Visitor();
v.Visit(expr);
return v.sourceExpression;
}
}
}
// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq.Expressions;
using System.Linq;
using System.Reflection;
using System.Data.Linq;
using System.Data.Linq.Mapping;
using System.Data.Linq.Provider;
using System.Diagnostics.CodeAnalysis;
namespace System.Data.Linq.SqlClient {
///
/// Method used for dealing with dynamic types. The ClrType of SqlNode is the
/// statically known type originating in the source expression tree. For methods
/// like GetType(), we need to know the dynamic type that will be constructed.
///
internal static class TypeSource {
private class Visitor : SqlVisitor {
class UnwrapStack {
public UnwrapStack(UnwrapStack last, bool unwrap) {
Last = last;
Unwrap = unwrap;
}
public UnwrapStack Last { get; private set; }
public bool Unwrap { get; private set; }
}
UnwrapStack UnwrapSequences;
internal SqlExpression sourceExpression;
internal Type sourceType;
[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.")]
internal override SqlNode Visit(SqlNode node) {
if (node == null)
return null;
sourceExpression = node as SqlExpression;
if (sourceExpression != null) {
Type type = sourceExpression.ClrType;
UnwrapStack unwrap = this.UnwrapSequences;
while (unwrap != null) {
if (unwrap.Unwrap) {
type = TypeSystem.GetElementType(type);
}
unwrap = unwrap.Last;
}
sourceType = type;
}
if (sourceType != null && TypeSystem.GetNonNullableType(sourceType).IsValueType) {
return node; // Value types can't also have a dynamic type.
}
if (sourceType != null && TypeSystem.HasIEnumerable(sourceType)) {
return node; // Sequences can't be polymorphic.
}
switch (node.NodeType) {
case SqlNodeType.ScalarSubSelect:
case SqlNodeType.Multiset:
case SqlNodeType.Element:
case SqlNodeType.SearchedCase:
case SqlNodeType.ClientCase:
case SqlNodeType.SimpleCase:
case SqlNodeType.Member:
case SqlNodeType.DiscriminatedType:
case SqlNodeType.New:
case SqlNodeType.FunctionCall:
case SqlNodeType.MethodCall:
case SqlNodeType.Convert: // Object identity does not survive convert. It does survive Cast.
// Dig no further.
return node;
case SqlNodeType.TypeCase:
sourceType = ((SqlTypeCase)node).RowType.Type;
return node;
case SqlNodeType.Link:
sourceType = ((SqlLink)node).RowType.Type;
return node;
case SqlNodeType.Table:
sourceType = ((SqlTable)node).RowType.Type;
return node;
case SqlNodeType.Value:
SqlValue val = (SqlValue)node;
if (val.Value != null) {
// In some cases the ClrType of a Value node may
// differ from the actual runtime type of the value.
// Therefore, we ensure here that the correct type is set.
sourceType = val.Value.GetType();
}
return node;
}
return base.Visit(node);
}
internal override SqlSelect VisitSelect(SqlSelect select) {
/*
* We're travelling through of something like:
*
* SELECT
* FROM
*
* Inside the expression there may be a reference to that
* represents the dynamic type that we're trying to discover.
*
* In this case, the type relationship between AliasRef and Alias is
* T to IEnumerable.
*
* We need to remember to 'unpivot' the type of IEnumerable to
* get the correct dynamic type.
*
* Since SELECTs may be nested, we use a stack of pivots.
*
*/
this.UnwrapSequences = new UnwrapStack(this.UnwrapSequences, true);
VisitExpression(select.Selection);
this.UnwrapSequences = this.UnwrapSequences.Last;
return select;
}
internal override SqlExpression VisitAliasRef(SqlAliasRef aref) {
if (this.UnwrapSequences != null && this.UnwrapSequences.Unwrap) {
this.UnwrapSequences = new UnwrapStack(this.UnwrapSequences, false);
this.VisitAlias(aref.Alias);
this.UnwrapSequences = this.UnwrapSequences.Last;
} else {
this.VisitAlias(aref.Alias);
}
return aref;
}
internal override SqlExpression VisitColumnRef(SqlColumnRef cref) {
this.VisitColumn(cref.Column); // Travel through column references
return cref;
}
}
///
/// Get a MetaType that represents the dynamic type of the given node.
///
internal static MetaType GetSourceMetaType(SqlNode node, MetaModel model) {
Visitor v = new Visitor();
v.Visit(node);
Type type = v.sourceType;
type = TypeSystem.GetNonNullableType(type); // Emulate CLR's behavior: strip nullability from type.
return model.GetMetaType(type);
}
///
/// Retrieve the expression that will represent the _dynamic_ type of the
/// given expression. This is either a SqlDiscriminatedType or a SqlValue
/// of type Type.
///
internal static SqlExpression GetTypeSource(SqlExpression expr) {
Visitor v = new Visitor();
v.Visit(expr);
return v.sourceExpression;
}
}
}
// 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
- MessageSmuggler.cs
- TagMapCollection.cs
- QuaternionKeyFrameCollection.cs
- KernelTypeValidation.cs
- XmlSchemaObject.cs
- UpdateTranslator.cs
- AsyncWaitHandle.cs
- MembershipPasswordException.cs
- OleDbConnectionFactory.cs
- GestureRecognizer.cs
- LinqDataSourceValidationException.cs
- BasicHttpBindingCollectionElement.cs
- CLRBindingWorker.cs
- ExecutionScope.cs
- SecurityTimestamp.cs
- TableColumn.cs
- Publisher.cs
- DateTimePickerDesigner.cs
- DataGridViewRowCancelEventArgs.cs
- MappingItemCollection.cs
- DataDocumentXPathNavigator.cs
- MdiWindowListItemConverter.cs
- DataBindEngine.cs
- ButtonChrome.cs
- GeometryGroup.cs
- DeploymentSection.cs
- DataAccessor.cs
- SqlProviderUtilities.cs
- PrinterUnitConvert.cs
- DataObject.cs
- SettingsSavedEventArgs.cs
- DictionaryContent.cs
- RedirectionProxy.cs
- EntityClientCacheKey.cs
- ObjectConverter.cs
- counter.cs
- FacetDescriptionElement.cs
- isolationinterop.cs
- FlowPosition.cs
- HostedHttpTransportManager.cs
- ErrorRuntimeConfig.cs
- Fault.cs
- HtmlMeta.cs
- ArrayList.cs
- TextElementEditingBehaviorAttribute.cs
- BitStack.cs
- CollectionViewGroup.cs
- CompoundFileIOPermission.cs
- ToolStripSeparatorRenderEventArgs.cs
- ObjectSecurity.cs
- PersonalizationProviderHelper.cs
- EncodingTable.cs
- Rotation3DKeyFrameCollection.cs
- NamespaceCollection.cs
- XmlElementAttributes.cs
- SqlDependencyListener.cs
- _Win32.cs
- DocumentSequence.cs
- Transform3D.cs
- WpfXamlType.cs
- RequestBringIntoViewEventArgs.cs
- ObjectManager.cs
- ChainOfResponsibility.cs
- ThousandthOfEmRealDoubles.cs
- ChtmlTextWriter.cs
- XamlGridLengthSerializer.cs
- Trace.cs
- SqlUdtInfo.cs
- SendMailErrorEventArgs.cs
- MetadataPropertyAttribute.cs
- Code.cs
- IncrementalHitTester.cs
- MessageQueueException.cs
- lengthconverter.cs
- XamlTypeMapper.cs
- MatrixStack.cs
- ContainerVisual.cs
- StringArrayConverter.cs
- ListControlConvertEventArgs.cs
- AstTree.cs
- CursorConverter.cs
- TimeSpan.cs
- DataGridViewCellPaintingEventArgs.cs
- SByteConverter.cs
- PackageDigitalSignature.cs
- ArgumentOutOfRangeException.cs
- WebSysDescriptionAttribute.cs
- HandlerBase.cs
- WeakReadOnlyCollection.cs
- ThreadAttributes.cs
- MiniLockedBorderGlyph.cs
- VSWCFServiceContractGenerator.cs
- Transform.cs
- _SafeNetHandles.cs
- TextContainerHelper.cs
- PeerNearMe.cs
- ValueUnavailableException.cs
- ADMembershipProvider.cs
- WebServiceReceiveDesigner.cs
- ErrorWebPart.cs