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
- CapabilitiesAssignment.cs
- MLangCodePageEncoding.cs
- StandardRuntimeEnumValidatorAttribute.cs
- IsolatedStorageException.cs
- HebrewCalendar.cs
- WebPartRestoreVerb.cs
- ModelItemDictionaryImpl.cs
- CurrentChangingEventManager.cs
- IdentityValidationException.cs
- AssemblyBuilder.cs
- DbConnectionPool.cs
- dsa.cs
- Binding.cs
- WebBrowserDesigner.cs
- Simplifier.cs
- NameSpaceEvent.cs
- TableItemProviderWrapper.cs
- TextRunCacheImp.cs
- OleDbRowUpdatingEvent.cs
- MessagePartProtectionMode.cs
- KeyFrames.cs
- GenericTypeParameterBuilder.cs
- GridEntry.cs
- HitTestParameters3D.cs
- RectValueSerializer.cs
- XPathDocumentBuilder.cs
- DataFormats.cs
- PenCursorManager.cs
- TraceProvider.cs
- SystemColors.cs
- DnsPermission.cs
- securitycriticaldata.cs
- LinqDataSourceStatusEventArgs.cs
- KeyboardEventArgs.cs
- HGlobalSafeHandle.cs
- TagPrefixInfo.cs
- StringFunctions.cs
- NativeMethods.cs
- MetadataArtifactLoaderComposite.cs
- CaseStatement.cs
- ZipIOCentralDirectoryFileHeader.cs
- TargetParameterCountException.cs
- MetadataProperty.cs
- DataKey.cs
- StyleXamlParser.cs
- SQLChars.cs
- Substitution.cs
- Assembly.cs
- XmlRootAttribute.cs
- XmlWriterSettings.cs
- SqlDataSourceCommandEventArgs.cs
- StringReader.cs
- WindowProviderWrapper.cs
- ProfileBuildProvider.cs
- CopyCodeAction.cs
- SafeRegistryHandle.cs
- SmtpTransport.cs
- PersonalizationStateInfo.cs
- _ConnectionGroup.cs
- FeatureSupport.cs
- Nodes.cs
- DocobjHost.cs
- TakeOrSkipWhileQueryOperator.cs
- SymLanguageVendor.cs
- Library.cs
- SqlFileStream.cs
- ICspAsymmetricAlgorithm.cs
- TypeInitializationException.cs
- PrivilegeNotHeldException.cs
- GridViewAutomationPeer.cs
- XamlReaderHelper.cs
- ListBoxChrome.cs
- EventSetterHandlerConverter.cs
- ObjectStateEntryDbDataRecord.cs
- securitycriticaldataClass.cs
- LayoutTableCell.cs
- FlagsAttribute.cs
- SoapCodeExporter.cs
- ScrollBarRenderer.cs
- TraceInternal.cs
- ManipulationDevice.cs
- X509CertificateCollection.cs
- PropertyIDSet.cs
- ComponentEditorForm.cs
- CheckPair.cs
- UInt16Storage.cs
- Opcode.cs
- XmlDataDocument.cs
- HttpException.cs
- PenContexts.cs
- DocumentApplication.cs
- DataGridViewRowPrePaintEventArgs.cs
- PackagingUtilities.cs
- StreamReader.cs
- RadialGradientBrush.cs
- AutoGeneratedFieldProperties.cs
- EventLogPermissionEntry.cs
- UInt32.cs
- SafeNativeMethods.cs
- SpotLight.cs