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
- RuleSettings.cs
- SystemTcpStatistics.cs
- ServerReliableChannelBinder.cs
- DbSource.cs
- SequentialOutput.cs
- WithParamAction.cs
- StateManagedCollection.cs
- FormattedTextSymbols.cs
- SafeHandle.cs
- HelpInfo.cs
- WindowsContainer.cs
- RemotingService.cs
- SynchronizingStream.cs
- metadatamappinghashervisitor.cs
- HtmlShim.cs
- SpanIndex.cs
- OracleCommandBuilder.cs
- RuntimeArgumentHandle.cs
- XslVisitor.cs
- SourceFileInfo.cs
- StringFreezingAttribute.cs
- UrlMapping.cs
- RelationshipEnd.cs
- FormsAuthenticationUserCollection.cs
- ExecutionContext.cs
- ButtonFlatAdapter.cs
- MessageQueueAccessControlEntry.cs
- EndSelectCardRequest.cs
- PowerStatus.cs
- BitmapEffectDrawingContextWalker.cs
- _HTTPDateParse.cs
- DocumentsTrace.cs
- CalendarDesigner.cs
- ByteArrayHelperWithString.cs
- ECDsa.cs
- Axis.cs
- XmlAtomicValue.cs
- PseudoWebRequest.cs
- RequestContextBase.cs
- EntitySet.cs
- PartitionedDataSource.cs
- SynchronizedDispatch.cs
- SharedPerformanceCounter.cs
- PointAnimationUsingPath.cs
- ExpressionsCollectionEditor.cs
- CommandCollectionEditor.cs
- columnmapfactory.cs
- XmlProcessingInstruction.cs
- cookieexception.cs
- ClientScriptItemCollection.cs
- TextContainerChangeEventArgs.cs
- BamlRecordReader.cs
- DropShadowBitmapEffect.cs
- SqlCacheDependencyDatabaseCollection.cs
- ObfuscateAssemblyAttribute.cs
- ServicePointManager.cs
- ScrollBar.cs
- safelink.cs
- GeometryHitTestResult.cs
- TerminateSequenceResponse.cs
- DatatypeImplementation.cs
- RemoteWebConfigurationHost.cs
- SoapReflector.cs
- HTTP_SERVICE_CONFIG_URLACL_KEY.cs
- GeometryGroup.cs
- ServiceInfo.cs
- DispatcherExceptionFilterEventArgs.cs
- BitStream.cs
- PartitionResolver.cs
- ConstructorNeedsTagAttribute.cs
- SizeIndependentAnimationStorage.cs
- PathTooLongException.cs
- FormParameter.cs
- JsonFormatWriterGenerator.cs
- ByteAnimation.cs
- PageVisual.cs
- Model3DGroup.cs
- LocalValueEnumerator.cs
- ListViewPagedDataSource.cs
- TemplateLookupAction.cs
- TemplateColumn.cs
- SignatureDescription.cs
- PagerStyle.cs
- Line.cs
- XPathBuilder.cs
- NestPullup.cs
- EventListener.cs
- TableCellCollection.cs
- FirstMatchCodeGroup.cs
- DataGridViewColumnDividerDoubleClickEventArgs.cs
- UIElementParaClient.cs
- BaseComponentEditor.cs
- ProcessModule.cs
- counter.cs
- MimeMultiPart.cs
- PublishLicense.cs
- CompositeCollection.cs
- Stacktrace.cs
- PropertyGridEditorPart.cs
- TimeZone.cs