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
- DependencyPropertyConverter.cs
- MemberPath.cs
- ButtonChrome.cs
- QilSortKey.cs
- FileSecurity.cs
- MulticastNotSupportedException.cs
- InstanceDataCollectionCollection.cs
- TextSegment.cs
- NetSectionGroup.cs
- EtwTrackingBehaviorElement.cs
- ZipIOFileItemStream.cs
- ArgumentNullException.cs
- XmlSchemaSimpleContent.cs
- mansign.cs
- AppliesToBehaviorDecisionTable.cs
- VectorConverter.cs
- CustomTrackingRecord.cs
- FormViewCommandEventArgs.cs
- LongValidator.cs
- EventDescriptor.cs
- Thickness.cs
- ToolStripRenderEventArgs.cs
- EdmFunctionAttribute.cs
- AuthorizationSection.cs
- httpstaticobjectscollection.cs
- PointHitTestResult.cs
- Rotation3DAnimationUsingKeyFrames.cs
- SystemResourceKey.cs
- Item.cs
- WizardPanelChangingEventArgs.cs
- LZCodec.cs
- IERequestCache.cs
- AcceptorSessionSymmetricMessageSecurityProtocol.cs
- List.cs
- FilteredReadOnlyMetadataCollection.cs
- SafeProcessHandle.cs
- DataControlFieldCell.cs
- SessionParameter.cs
- BorderSidesEditor.cs
- ResourceCategoryAttribute.cs
- OutputCacheSection.cs
- HashCoreRequest.cs
- TemplatedEditableDesignerRegion.cs
- WebScriptServiceHost.cs
- DiscoveryViaBehavior.cs
- EntityContainerEmitter.cs
- LinkGrep.cs
- XmlHierarchicalEnumerable.cs
- BooleanKeyFrameCollection.cs
- AssemblyNameEqualityComparer.cs
- NGCUIElementCollectionSerializerAsync.cs
- SafeSystemMetrics.cs
- UnsafeNativeMethods.cs
- IsolatedStoragePermission.cs
- ChannelSinkStacks.cs
- ButtonStandardAdapter.cs
- AppearanceEditorPart.cs
- CodeGeneratorAttribute.cs
- GCHandleCookieTable.cs
- XmlSerializerSection.cs
- GridViewItemAutomationPeer.cs
- HGlobalSafeHandle.cs
- ActiveXSerializer.cs
- PointAnimationClockResource.cs
- ApplicationException.cs
- HtmlTernaryTree.cs
- Confirm.cs
- AudioBase.cs
- LinearQuaternionKeyFrame.cs
- TargetParameterCountException.cs
- ImagingCache.cs
- DiscoveryClient.cs
- OutputScope.cs
- UrlMappingsSection.cs
- PrinterSettings.cs
- CompositionAdorner.cs
- GridViewHeaderRowPresenterAutomationPeer.cs
- CompoundFileStreamReference.cs
- WebExceptionStatus.cs
- ActivityExecutorDelegateInfo.cs
- AnnotationDocumentPaginator.cs
- DataKeyArray.cs
- FederatedMessageSecurityOverHttp.cs
- OrderPreservingPipeliningMergeHelper.cs
- __ConsoleStream.cs
- HtmlInputCheckBox.cs
- PointIndependentAnimationStorage.cs
- DesignerDataSourceView.cs
- OutputCacheProfileCollection.cs
- CfgSemanticTag.cs
- DesignerVerbCollection.cs
- DataServiceQueryOfT.cs
- KeyValuePairs.cs
- CultureTableRecord.cs
- PersonalizationStateInfo.cs
- Point4D.cs
- NodeFunctions.cs
- VarRemapper.cs
- WebServiceParameterData.cs
- ResourceExpressionBuilder.cs