Exemple #1
0
 protected virtual void VisitCastToken(CastToken token)
 {
     State.Write(Symbols.CAST);
     State.Write(Symbols.OpenParenthesis);
     VisitToken(token.Token);
     State.Write(Symbols.AS);
     VisitType(token);
     State.Write(Symbols.CloseParenthesis);
 }
        /// <summary>
        /// Binds a type segment token.
        /// </summary>
        /// <param name="castToken">The type segment token to bind.</param>
        /// <returns>The bound type segment token.</returns>
        protected virtual QueryNode BindCast(CastToken castToken)
        {
            ExceptionUtils.CheckArgumentNotNull(castToken, "typeSegmentToken");

            var childType = this.model.FindType(castToken.SegmentSpace + "." + castToken.SegmentName);

            // Check whether childType is a derived type of the type of its parent node
            QueryNode parent;
            IEdmType parentType;
            if (castToken.Source == null)
            {
                parent = null;
                parentType = this.parameter.ParameterType.Definition;
            }
            else
            {
                parent = this.Bind(castToken.Source);
                parentType = GetType(parent);
            }

            if (!childType.IsOrInheritsFrom(parentType))
            {
                throw new ODataException(Strings.MetadataBinder_HierarchyNotFollowed(childType.FullName(), parentType.ODataFullName()));
            }

            return new CastNode()
            {
                EdmType = childType,
                Source = (SingleValueQueryNode)parent
            };
        }
        protected override void VisitCastToken(CastToken token)
        {
            State.Write(Symbols.CAST, Symbols.OpenParenthesis);
            VisitToken(token.Token);
            State.Write(Symbols.AS);

            // cast supports only these data types:
            // BINARY[(N)]
            // CHAR[(N)][charset_info]
            // DATE
            // DATETIME
            // DECIMAL[(M[, D])]
            // NCHAR[(N)]
            // SIGNED[INTEGER]
            // TIME
            // UNSIGNED[INTEGER]

            CommonDbType?targetType;

            switch (token.DbType)
            {
            case CommonDbType.Bit:
            case CommonDbType.BigInt:
            case CommonDbType.SmallInt:
            case CommonDbType.TinyInt:
                targetType = CommonDbType.Int;
                break;

            case CommonDbType.Float:
            case CommonDbType.Money:
            case CommonDbType.Real:
            case CommonDbType.SmallMoney:
                targetType = CommonDbType.Decimal;
                break;

            case CommonDbType.NText:
            case CommonDbType.NVarChar:
            case CommonDbType.Xml:
                targetType = CommonDbType.NChar;
                break;

            case CommonDbType.UniqueIdentifier:
            case CommonDbType.Text:
            case CommonDbType.VarChar:
                targetType = CommonDbType.Char;
                break;

            case CommonDbType.SmallDateTime:
            case CommonDbType.Timestamp:
            case CommonDbType.Date:
            case CommonDbType.DateTime2:
            case CommonDbType.DateTimeOffset:
                targetType = CommonDbType.DateTime;
                break;

            case CommonDbType.VarBinary:
            case CommonDbType.Image:
            case CommonDbType.Variant:
                targetType = CommonDbType.Binary;
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }

            if (targetType != token.DbType)
            {
                var clonedToken = new CastToken
                {
                    Alias     = token.Alias,
                    DbType    = targetType,
                    Length    = token.Length,
                    Precision = token.Precision,
                    Scale     = token.Scale,
                    Token     = token.Token,
                };
                foreach (var parameter in token.Parameters)
                {
                    clonedToken.Parameters.Add(parameter);
                }
                foreach (var parameterValue in token.ParameterValues)
                {
                    clonedToken.ParameterValues.Add(parameterValue);
                }
                VisitType(clonedToken);
            }
            else
            {
                VisitType(token);
            }
            State.Write(Symbols.CloseParenthesis);
        }