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
- WebConfigurationFileMap.cs
- TargetInvocationException.cs
- HwndMouseInputProvider.cs
- ContentControl.cs
- CharAnimationUsingKeyFrames.cs
- SqlError.cs
- Publisher.cs
- Geometry3D.cs
- HyperLink.cs
- WindowsAltTab.cs
- HitTestWithPointDrawingContextWalker.cs
- BindingElementExtensionElement.cs
- MsmqIntegrationAppDomainProtocolHandler.cs
- activationcontext.cs
- UInt64Converter.cs
- TypeReference.cs
- CngKeyBlobFormat.cs
- Propagator.cs
- returneventsaver.cs
- BinaryConverter.cs
- CredentialSelector.cs
- RegexCompiler.cs
- CodeExpressionStatement.cs
- DodSequenceMerge.cs
- DataGridViewBand.cs
- NgenServicingAttributes.cs
- IndexedEnumerable.cs
- ComponentCollection.cs
- Graph.cs
- QilInvokeEarlyBound.cs
- EventOpcode.cs
- DataGridColumn.cs
- AnonymousIdentificationModule.cs
- MarkerProperties.cs
- Avt.cs
- SubpageParaClient.cs
- RadioButtonBaseAdapter.cs
- MeshGeometry3D.cs
- EncoderParameters.cs
- Rotation3D.cs
- EntityDesignerUtils.cs
- AbstractDataSvcMapFileLoader.cs
- EntitySqlException.cs
- RegistryKey.cs
- RectangleConverter.cs
- Condition.cs
- DataSourceSerializationException.cs
- TemplatedEditableDesignerRegion.cs
- SingleConverter.cs
- XPathDocumentNavigator.cs
- RewritingProcessor.cs
- WinFormsUtils.cs
- DurableTimerExtension.cs
- TypeDelegator.cs
- XmlSchemaGroupRef.cs
- NetStream.cs
- MembershipUser.cs
- HtmlInputCheckBox.cs
- UnsafeCollabNativeMethods.cs
- QuotedStringWriteStateInfo.cs
- ScrollViewerAutomationPeer.cs
- CompositeTypefaceMetrics.cs
- XmlSchemaInferenceException.cs
- CharAnimationUsingKeyFrames.cs
- XmlStreamStore.cs
- RedirectionProxy.cs
- DataBoundControlAdapter.cs
- SoapHttpTransportImporter.cs
- ContainerActivationHelper.cs
- BitmapPalette.cs
- UmAlQuraCalendar.cs
- ContainerSelectorBehavior.cs
- Trace.cs
- PrivateFontCollection.cs
- RegexFCD.cs
- AsyncContentLoadedEventArgs.cs
- KnownBoxes.cs
- UnorderedHashRepartitionStream.cs
- Transform.cs
- Cursors.cs
- WindowsScroll.cs
- DataServiceClientException.cs
- MTConfigUtil.cs
- TextRange.cs
- KeyGestureValueSerializer.cs
- ImplicitInputBrush.cs
- EventSinkHelperWriter.cs
- MethodBuilderInstantiation.cs
- DetailsViewDesigner.cs
- FlowDocumentView.cs
- FragmentNavigationEventArgs.cs
- Evidence.cs
- PtsCache.cs
- AttributeSetAction.cs
- FontUnitConverter.cs
- _TransmitFileOverlappedAsyncResult.cs
- XamlSerializationHelper.cs
- PrintDialog.cs
- SecurityChannelFaultConverter.cs
- XmlReaderSettings.cs