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
- UIPropertyMetadata.cs
- ISFTagAndGuidCache.cs
- IntegerCollectionEditor.cs
- Input.cs
- SingleKeyFrameCollection.cs
- InternalControlCollection.cs
- WebPageTraceListener.cs
- TimeZone.cs
- Encoder.cs
- FixedElement.cs
- ExpressionStringBuilder.cs
- RightsManagementEncryptedStream.cs
- ContextActivityUtils.cs
- EditableRegion.cs
- LinkUtilities.cs
- ExpandCollapsePattern.cs
- ZipIOFileItemStream.cs
- XPathNodeInfoAtom.cs
- LocalBuilder.cs
- IPCCacheManager.cs
- XPathAncestorIterator.cs
- CodeMethodMap.cs
- ValidationHelpers.cs
- StringUtil.cs
- ClipboardProcessor.cs
- HttpHandlerAction.cs
- CommentEmitter.cs
- BezierSegment.cs
- RequestResizeEvent.cs
- initElementDictionary.cs
- Attributes.cs
- JoinCqlBlock.cs
- SqlTransaction.cs
- SerialPinChanges.cs
- AssemblyNameProxy.cs
- GridViewAutomationPeer.cs
- LogicalExpr.cs
- CommandHelper.cs
- EdmFunctions.cs
- SelectedPathEditor.cs
- CodeAccessPermission.cs
- Point3DCollection.cs
- FilteredAttributeCollection.cs
- EntityConnectionStringBuilderItem.cs
- FileAuthorizationModule.cs
- BlobPersonalizationState.cs
- ObjectPersistData.cs
- ResourceAttributes.cs
- PathFigure.cs
- ServiceOperationParameter.cs
- Effect.cs
- CompilationLock.cs
- SamlDelegatingWriter.cs
- Single.cs
- PersistChildrenAttribute.cs
- ParenthesizePropertyNameAttribute.cs
- AnnotationHelper.cs
- PromptEventArgs.cs
- XmlParser.cs
- PropertySet.cs
- ScriptRegistrationManager.cs
- InkCanvasSelectionAdorner.cs
- StructuredType.cs
- HttpDebugHandler.cs
- RegexBoyerMoore.cs
- GraphicsPath.cs
- VisualStyleRenderer.cs
- WebBrowsableAttribute.cs
- Missing.cs
- SystemThemeKey.cs
- FillErrorEventArgs.cs
- StringAnimationBase.cs
- CapabilitiesUse.cs
- DataGridViewIntLinkedList.cs
- Sequence.cs
- MenuItemBindingCollection.cs
- TraceSwitch.cs
- DataGridViewRowDividerDoubleClickEventArgs.cs
- XmlExceptionHelper.cs
- GridToolTip.cs
- CompModSwitches.cs
- Brush.cs
- hresults.cs
- XXXOnTypeBuilderInstantiation.cs
- XmlObjectSerializerWriteContextComplex.cs
- ListControl.cs
- BuiltInExpr.cs
- Header.cs
- OpenTypeLayout.cs
- _NestedMultipleAsyncResult.cs
- CombinedHttpChannel.cs
- XmlSchemaSequence.cs
- X509ThumbprintKeyIdentifierClause.cs
- SqlTransaction.cs
- RawStylusSystemGestureInputReport.cs
- AsyncDataRequest.cs
- DelegateArgument.cs
- WindowsFormsHelpers.cs
- ScriptReference.cs
- Trace.cs