Code:
/ Net / Net / 3.5.50727.3053 / DEVDIV / depot / DevDiv / releases / Orcas / SP / 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
- IDataContractSurrogate.cs
- EventListener.cs
- Unit.cs
- GenericIdentity.cs
- ReceiveSecurityHeaderEntry.cs
- HTMLTagNameToTypeMapper.cs
- Line.cs
- ContentType.cs
- ReflectEventDescriptor.cs
- WindowsGraphicsCacheManager.cs
- HtmlFormWrapper.cs
- Pkcs9Attribute.cs
- MailSettingsSection.cs
- Helper.cs
- XmlSortKeyAccumulator.cs
- FigureParagraph.cs
- DataGridViewSelectedColumnCollection.cs
- ModelProperty.cs
- RNGCryptoServiceProvider.cs
- PersonalizationProviderHelper.cs
- OutputCacheModule.cs
- MasterPage.cs
- InfoCardSymmetricAlgorithm.cs
- MethodBuilderInstantiation.cs
- SchemaImporterExtensionsSection.cs
- XamlStyleSerializer.cs
- SettingsPropertyNotFoundException.cs
- EdmTypeAttribute.cs
- SafeEventLogWriteHandle.cs
- QueryInterceptorAttribute.cs
- RegexReplacement.cs
- UmAlQuraCalendar.cs
- DataGridCheckBoxColumn.cs
- HyperLinkStyle.cs
- RouteUrlExpressionBuilder.cs
- Point4DValueSerializer.cs
- QilInvokeEarlyBound.cs
- ListDataBindEventArgs.cs
- SerializationInfoEnumerator.cs
- ColumnCollection.cs
- InvalidCastException.cs
- CategoryNameCollection.cs
- WebServiceMethodData.cs
- ConnectionStringsExpressionBuilder.cs
- EventMetadata.cs
- PageClientProxyGenerator.cs
- WebDescriptionAttribute.cs
- IPeerNeighbor.cs
- CodeArrayIndexerExpression.cs
- SplitterEvent.cs
- ItemType.cs
- DuplexChannel.cs
- ErrorHandler.cs
- HttpCacheParams.cs
- PersonalizationStateQuery.cs
- RowUpdatingEventArgs.cs
- WebPartDescription.cs
- Deflater.cs
- TextFragmentEngine.cs
- DrawingServices.cs
- VarRefManager.cs
- glyphs.cs
- CaseInsensitiveOrdinalStringComparer.cs
- SecurityContext.cs
- HierarchicalDataBoundControl.cs
- InternalConfigRoot.cs
- QualifiedCellIdBoolean.cs
- XamlReader.cs
- XmlUrlResolver.cs
- TraceSection.cs
- BitmapEffectInputConnector.cs
- RelatedEnd.cs
- SqlMethodCallConverter.cs
- FullTextLine.cs
- SecurityStandardsManager.cs
- GridItemProviderWrapper.cs
- MessageDecoder.cs
- TransformProviderWrapper.cs
- UserInitiatedNavigationPermission.cs
- SocketPermission.cs
- CachingHintValidation.cs
- SmiTypedGetterSetter.cs
- MethodImplAttribute.cs
- DynamicRendererThreadManager.cs
- TextLineResult.cs
- KeyValueConfigurationCollection.cs
- CancellationHandlerDesigner.cs
- DbFunctionCommandTree.cs
- TreeIterator.cs
- PopupRoot.cs
- StringOutput.cs
- EditingCoordinator.cs
- TextEndOfSegment.cs
- PasswordBox.cs
- SortedDictionary.cs
- _AutoWebProxyScriptEngine.cs
- Tile.cs
- EmbeddedMailObject.cs
- WebPartConnectionCollection.cs
- SpeechEvent.cs