Code:
/ Dotnetfx_Vista_SP2 / Dotnetfx_Vista_SP2 / 8.0.50727.4016 / DEVDIV / depot / DevDiv / releases / Orcas / QFE / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlMethodTransformer.cs / 2 / SqlMethodTransformer.cs
using System;
using System.Collections.Generic;
using System.Text;
using System.Data.Linq;
namespace System.Data.Linq.SqlClient {
///
/// After retyping and conversions take place, some functions need to be changed into more suitable calls.
/// Example: LEN -> DATALENGTH for long text types.
///
internal class SqlMethodTransformer : SqlVisitor {
protected SqlFactory sql;
internal SqlMethodTransformer(SqlFactory sql) {
this.sql = sql;
}
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) {
// process the arguments
SqlExpression result = base.VisitFunctionCall(fc);
if (result is SqlFunctionCall) {
SqlFunctionCall resultFunctionCall = (SqlFunctionCall)result;
if (resultFunctionCall.Name == "LEN") {
SqlExpression expr = resultFunctionCall.Arguments[0];
if (expr.SqlType.IsLargeType && !expr.SqlType.SupportsLength) {
result = sql.DATALENGTH(expr);
if (expr.SqlType.IsUnicodeType) {
result = sql.ConvertToInt(sql.Divide(result, sql.ValueFromObject(2, expr.SourceExpression)));
}
}
}
// If the return type of the sql function is not compatible with
// the expected CLR type of the function, inject a conversion. This
// step must be performed AFTER SqlRetyper has run.
Type clrType = resultFunctionCall.SqlType.GetClosestRuntimeType();
bool skipConversion = SqlMethodTransformer.SkipConversionForDateAdd(resultFunctionCall.Name,
resultFunctionCall.ClrType,
clrType);
if ((resultFunctionCall.ClrType != clrType) && !skipConversion) {
result = sql.ConvertTo(resultFunctionCall.ClrType, resultFunctionCall);
}
}
return result;
}
internal override SqlExpression VisitUnaryOperator(SqlUnary fc) {
// process the arguments
SqlExpression result = base.VisitUnaryOperator(fc);
if (result is SqlUnary) {
SqlUnary unary = (SqlUnary)result;
switch (unary.NodeType) {
case SqlNodeType.ClrLength:
SqlExpression expr = unary.Operand;
result = sql.DATALENGTH(expr);
if (expr.SqlType.IsUnicodeType) {
result = sql.Divide(result, sql.ValueFromObject(2, expr.SourceExpression));
}
result = sql.ConvertToInt(result);
break;
default:
break;
}
}
return result;
}
// We don't inject a conversion for DATEADD if doing so will downgrade the result to
// a less precise type.
//
private static bool SkipConversionForDateAdd(string functionName, Type expected, Type actual) {
if (string.Compare(functionName, "DATEADD", StringComparison.OrdinalIgnoreCase) != 0)
return false;
return (expected == typeof(DateTime) && actual == typeof(DateTimeOffset));
}
}
}
// 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;
namespace System.Data.Linq.SqlClient {
///
/// After retyping and conversions take place, some functions need to be changed into more suitable calls.
/// Example: LEN -> DATALENGTH for long text types.
///
internal class SqlMethodTransformer : SqlVisitor {
protected SqlFactory sql;
internal SqlMethodTransformer(SqlFactory sql) {
this.sql = sql;
}
internal override SqlExpression VisitFunctionCall(SqlFunctionCall fc) {
// process the arguments
SqlExpression result = base.VisitFunctionCall(fc);
if (result is SqlFunctionCall) {
SqlFunctionCall resultFunctionCall = (SqlFunctionCall)result;
if (resultFunctionCall.Name == "LEN") {
SqlExpression expr = resultFunctionCall.Arguments[0];
if (expr.SqlType.IsLargeType && !expr.SqlType.SupportsLength) {
result = sql.DATALENGTH(expr);
if (expr.SqlType.IsUnicodeType) {
result = sql.ConvertToInt(sql.Divide(result, sql.ValueFromObject(2, expr.SourceExpression)));
}
}
}
// If the return type of the sql function is not compatible with
// the expected CLR type of the function, inject a conversion. This
// step must be performed AFTER SqlRetyper has run.
Type clrType = resultFunctionCall.SqlType.GetClosestRuntimeType();
bool skipConversion = SqlMethodTransformer.SkipConversionForDateAdd(resultFunctionCall.Name,
resultFunctionCall.ClrType,
clrType);
if ((resultFunctionCall.ClrType != clrType) && !skipConversion) {
result = sql.ConvertTo(resultFunctionCall.ClrType, resultFunctionCall);
}
}
return result;
}
internal override SqlExpression VisitUnaryOperator(SqlUnary fc) {
// process the arguments
SqlExpression result = base.VisitUnaryOperator(fc);
if (result is SqlUnary) {
SqlUnary unary = (SqlUnary)result;
switch (unary.NodeType) {
case SqlNodeType.ClrLength:
SqlExpression expr = unary.Operand;
result = sql.DATALENGTH(expr);
if (expr.SqlType.IsUnicodeType) {
result = sql.Divide(result, sql.ValueFromObject(2, expr.SourceExpression));
}
result = sql.ConvertToInt(result);
break;
default:
break;
}
}
return result;
}
// We don't inject a conversion for DATEADD if doing so will downgrade the result to
// a less precise type.
//
private static bool SkipConversionForDateAdd(string functionName, Type expected, Type actual) {
if (string.Compare(functionName, "DATEADD", StringComparison.OrdinalIgnoreCase) != 0)
return false;
return (expected == typeof(DateTime) && actual == typeof(DateTimeOffset));
}
}
}
// 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
- RefExpr.cs
- WebBrowserPermission.cs
- XsdDuration.cs
- NopReturnReader.cs
- TextPointerBase.cs
- ClassHandlersStore.cs
- IFormattable.cs
- EmptyStringExpandableObjectConverter.cs
- DetailsViewRowCollection.cs
- WindowsTreeView.cs
- UIElementParagraph.cs
- DropSourceBehavior.cs
- HtmlAnchor.cs
- PLINQETWProvider.cs
- DrawListViewItemEventArgs.cs
- MexNamedPipeBindingElement.cs
- RegexStringValidatorAttribute.cs
- _NegoState.cs
- UnionExpr.cs
- FixedSchema.cs
- TextPatternIdentifiers.cs
- XmlSchemaExternal.cs
- SystemInformation.cs
- CardSpacePolicyElement.cs
- PrintPreviewGraphics.cs
- PropertyItemInternal.cs
- TakeOrSkipWhileQueryOperator.cs
- ObjectNavigationPropertyMapping.cs
- XmlQueryRuntime.cs
- DataGridViewEditingControlShowingEventArgs.cs
- SlipBehavior.cs
- ObjectPersistData.cs
- BuildProvider.cs
- EntityProviderFactory.cs
- ToolStripScrollButton.cs
- XsltContext.cs
- BorderGapMaskConverter.cs
- TaskFormBase.cs
- CustomAssemblyResolver.cs
- RoutingExtensionElement.cs
- ParameterModifier.cs
- SystemTcpStatistics.cs
- InProcStateClientManager.cs
- SystemIPv4InterfaceProperties.cs
- EventMappingSettingsCollection.cs
- XmlSchemaType.cs
- DetailsViewUpdatedEventArgs.cs
- GPStream.cs
- NewExpression.cs
- CacheMemory.cs
- odbcmetadatacollectionnames.cs
- SchemaDeclBase.cs
- BaseCollection.cs
- ProfileProvider.cs
- ListenerAdapterBase.cs
- XpsFixedDocumentSequenceReaderWriter.cs
- EllipseGeometry.cs
- MetadataArtifactLoaderFile.cs
- TextDecorationCollection.cs
- RegexCompilationInfo.cs
- EncryptedXml.cs
- ObjectDataProvider.cs
- OdbcPermission.cs
- XmlNodeReader.cs
- AmbientLight.cs
- GridLengthConverter.cs
- Group.cs
- ObjectComplexPropertyMapping.cs
- IgnoreFlushAndCloseStream.cs
- HTTPNotFoundHandler.cs
- EventlogProvider.cs
- SystemIPGlobalProperties.cs
- MessageVersionConverter.cs
- ViewBox.cs
- HttpCapabilitiesSectionHandler.cs
- XamlBuildProvider.cs
- WindowsListViewSubItem.cs
- StyleTypedPropertyAttribute.cs
- KeyValueConfigurationCollection.cs
- DataViewManager.cs
- SmiTypedGetterSetter.cs
- SQLRoleProvider.cs
- CheckBoxRenderer.cs
- DotAtomReader.cs
- RawKeyboardInputReport.cs
- GridView.cs
- ToolStripSplitButton.cs
- ReadOnlyHierarchicalDataSourceView.cs
- Object.cs
- SerializationFieldInfo.cs
- PasswordPropertyTextAttribute.cs
- StyleModeStack.cs
- BuildProviderUtils.cs
- SoapServerProtocol.cs
- IHttpResponseInternal.cs
- CompareInfo.cs
- BooleanFacetDescriptionElement.cs
- XmlSigningNodeWriter.cs
- BasicExpandProvider.cs
- DataObjectEventArgs.cs