Code:
/ 4.0 / 4.0 / DEVDIV_TFS / Dev10 / Releases / RTMRel / ndp / fx / src / DLinq / Dlinq / SqlClient / Query / SqlMethodTransformer.cs / 1305376 / 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
- DateTimeFormatInfoScanner.cs
- SourceSwitch.cs
- WindowInteropHelper.cs
- Int64Animation.cs
- XslCompiledTransform.cs
- SharedPerformanceCounter.cs
- ProviderBase.cs
- ClientEndpointLoader.cs
- MessageQueueTransaction.cs
- Substitution.cs
- WindowsMenu.cs
- ItemCheckedEvent.cs
- ImageCodecInfoPrivate.cs
- InProcStateClientManager.cs
- GestureRecognizer.cs
- KeyEvent.cs
- FullTextState.cs
- DataTableClearEvent.cs
- AutomationPropertyInfo.cs
- TaiwanLunisolarCalendar.cs
- Util.cs
- DockAndAnchorLayout.cs
- ObjectTokenCategory.cs
- Variable.cs
- CodeThrowExceptionStatement.cs
- FrameworkContentElementAutomationPeer.cs
- UniformGrid.cs
- HtmlShim.cs
- SetterBaseCollection.cs
- DefaultHttpHandler.cs
- CharAnimationUsingKeyFrames.cs
- SqlCommandSet.cs
- QueueSurrogate.cs
- TextBox.cs
- TypeUnloadedException.cs
- ArgIterator.cs
- AmbiguousMatchException.cs
- MulticastOption.cs
- FormattedTextSymbols.cs
- MessageFilter.cs
- MailWebEventProvider.cs
- InputMethod.cs
- ISFTagAndGuidCache.cs
- CodeGenerator.cs
- NTAccount.cs
- DiscreteKeyFrames.cs
- OleDbPermission.cs
- GuidTagList.cs
- PointUtil.cs
- ControlIdConverter.cs
- NotifyParentPropertyAttribute.cs
- SqlDataSourceSelectingEventArgs.cs
- ObjectDataSourceMethodEventArgs.cs
- AdjustableArrowCap.cs
- Switch.cs
- QuotedPrintableStream.cs
- ContractMethodInfo.cs
- SR.cs
- ManagementEventArgs.cs
- Crc32.cs
- Positioning.cs
- QilFunction.cs
- PathFigureCollection.cs
- AutomationElement.cs
- FlowDocumentReaderAutomationPeer.cs
- RelativeSource.cs
- UInt16Converter.cs
- CounterSampleCalculator.cs
- RepeaterCommandEventArgs.cs
- WebPartRestoreVerb.cs
- XpsFixedPageReaderWriter.cs
- WebPartConnection.cs
- StyleCollectionEditor.cs
- CroppedBitmap.cs
- ThreadNeutralSemaphore.cs
- SqlDataSourceCache.cs
- HttpClientCertificate.cs
- SerialErrors.cs
- WebPartConnectionsCancelEventArgs.cs
- ReachVisualSerializerAsync.cs
- MeasurementDCInfo.cs
- AccessibleObject.cs
- WebConfigManager.cs
- InstallerTypeAttribute.cs
- Convert.cs
- HwndSource.cs
- SystemColorTracker.cs
- Rotation3DKeyFrameCollection.cs
- CodeAccessPermission.cs
- XmlILConstructAnalyzer.cs
- DropShadowEffect.cs
- StringUtil.cs
- DispatcherFrame.cs
- PieceDirectory.cs
- FixedSOMContainer.cs
- HasCopySemanticsAttribute.cs
- ObjectItemCollectionAssemblyCacheEntry.cs
- AttributeUsageAttribute.cs
- SqlReferenceCollection.cs
- XamlTemplateSerializer.cs