Пример #1
0
        /// <summary>
        /// Converts a value to primitive value.
        /// </summary>
        /// <param name="value">The value.</param>
        /// <param name="propertyType">Type of the property.</param>
        /// <returns>The converted value if the value can be converted</returns>
        internal object ConvertPrimitiveValue(object value, Type propertyType)
        {
            // System.Xml.Linq.XElement and System.Data.Linq.Binaries primitive types are not supported by ODataLib directly,
            // so if the property is of one of those types, we need to convert the value to that type here.
            if (propertyType != null && value != null)
            {
                Debug.Assert(PrimitiveType.IsKnownNullableType(propertyType), "GetPrimitiveValue must be called only for primitive types");

                // Fast path for the supported primitive types that have a type code and are supported by ODataLib.
                Type     nonNullablePropertyType = Nullable.GetUnderlyingType(propertyType) ?? propertyType;
                TypeCode typeCode = PlatformHelper.GetTypeCode(nonNullablePropertyType);
                switch (typeCode)
                {
                case TypeCode.Boolean:      // fall through
                case TypeCode.Byte:         // fall through
                case TypeCode.DateTime:     // fall through
                case TypeCode.Decimal:      // fall through
                case TypeCode.Double:       // fall through
                case TypeCode.Int16:        // fall through
                case TypeCode.Int32:        // fall through
                case TypeCode.Int64:        // fall through
                case TypeCode.SByte:        // fall through
                case TypeCode.Single:       // fall through
                case TypeCode.String:
                    return(this.ConvertValueIfNeeded(value, propertyType));
                }

                // Do the conversion for types that are not supported by ODataLib e.g. char[], char, etc
                // PropertyType might be nullable. Hence to avoid nullable checks, we currently check for
                // primitiveType.ClrType
                if (typeCode == TypeCode.Char ||
                    typeCode == TypeCode.UInt16 ||
                    typeCode == TypeCode.UInt32 ||
                    typeCode == TypeCode.UInt64 ||
                    nonNullablePropertyType == typeof(Char[]) ||
                    nonNullablePropertyType == typeof(Type) ||
                    nonNullablePropertyType == typeof(Uri) ||
                    nonNullablePropertyType == typeof(Xml.Linq.XDocument) ||
                    nonNullablePropertyType == typeof(Xml.Linq.XElement))
                {
                    PrimitiveType primitiveType;
                    PrimitiveType.TryGetPrimitiveType(propertyType, out primitiveType);
                    Debug.Assert(primitiveType != null, "must be a known primitive type");

                    string stringValue = (string)this.ConvertValueIfNeeded(value, typeof(string));
                    return(primitiveType.TypeConverter.Parse(stringValue));
                }

#if !ASTORIA_LIGHT && !PORTABLELIB
                if (propertyType == BinaryTypeConverter.BinaryType)
                {
                    byte[] byteArray = (byte[])this.ConvertValueIfNeeded(value, typeof(byte[]));
                    Debug.Assert(byteArray != null, "If the property is of type System.Data.Linq.Binary then ODataLib should have read it as byte[].");
                    return(Activator.CreateInstance(BinaryTypeConverter.BinaryType, byteArray));
                }
#endif
            }

            return(this.ConvertValueIfNeeded(value, propertyType));
        }
Пример #2
0
        /// <summary>
        /// Converts a primitive OData value to the corresponding <see cref="IEdmDelayedValue"/>.
        /// </summary>
        /// <param name="primitiveValue">The primitive OData value to convert.</param>
        /// <param name="type">The <see cref="IEdmTypeReference"/> for the primitive value (if available).</param>
        /// <returns>An <see cref="IEdmDelayedValue"/> for the <paramref name="primitiveValue"/>.</returns>
        internal static IEdmDelayedValue ConvertPrimitiveValue(object primitiveValue, IEdmPrimitiveTypeReference type)
        {
#if !ASTORIA_CLIENT
            DebugUtils.CheckNoExternalCallers();
#endif
            Debug.Assert(primitiveValue != null, "primitiveValue != null");

            TypeCode typeCode = PlatformHelpers.GetTypeCode(primitiveValue.GetType());
            switch (typeCode)
            {
            case TypeCode.Boolean:
                type = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Boolean);
                return(new EdmBooleanConstant(type, (bool)primitiveValue));

            case TypeCode.Byte:
                type = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Byte);
                return(new EdmIntegerConstant(type, (byte)primitiveValue));

            case TypeCode.SByte:
                type = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.SByte);
                return(new EdmIntegerConstant(type, (sbyte)primitiveValue));

            case TypeCode.Int16:
                type = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Int16);
                return(new EdmIntegerConstant(type, (Int16)primitiveValue));

            case TypeCode.Int32:
                type = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Int32);
                return(new EdmIntegerConstant(type, (Int32)primitiveValue));

            case TypeCode.Int64:
                type = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Int64);
                return(new EdmIntegerConstant(type, (Int64)primitiveValue));

            case TypeCode.DateTime:
                IEdmTemporalTypeReference dateTimeType = (IEdmTemporalTypeReference)EnsurePrimitiveType(type, EdmPrimitiveTypeKind.DateTime);
                return(new EdmDateTimeConstant(dateTimeType, (DateTime)primitiveValue));

            case TypeCode.Decimal:
                IEdmDecimalTypeReference decimalType = (IEdmDecimalTypeReference)EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Decimal);
                return(new EdmDecimalConstant(decimalType, (decimal)primitiveValue));

            case TypeCode.Single:
                type = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Single);
                return(new EdmFloatingConstant(type, (Single)primitiveValue));

            case TypeCode.Double:
                type = EnsurePrimitiveType(type, EdmPrimitiveTypeKind.Double);
                return(new EdmFloatingConstant(type, (double)primitiveValue));

            case TypeCode.String:
                IEdmStringTypeReference stringType = (IEdmStringTypeReference)EnsurePrimitiveType(type, EdmPrimitiveTypeKind.String);
                return(new EdmStringConstant(stringType, (string)primitiveValue));

            default:
                return(ConvertPrimitiveValueWithoutTypeCode(primitiveValue, type));
            }
        }
Пример #3
0
        /// <summary>
        /// Converts a non-spatial primitive value to the target type.
        /// </summary>
        /// <param name="value">The value to convert.</param>
        /// <param name="targetType">The target type of the conversion.</param>
        /// <returns>The converted value.</returns>
        private static object ConvertNonSpatialValue(object value, Type targetType)
        {
            Debug.Assert(value != null, "value != null");
            TypeCode targetTypeCode = PlatformHelper.GetTypeCode(targetType);

            // These types can be safely converted to directly, as there is no risk of precision being lost.
            switch (targetTypeCode)
            {
            case TypeCode.Boolean:
            case TypeCode.Byte:
            case TypeCode.SByte:
            case TypeCode.Int16:
            case TypeCode.Int32:
            case TypeCode.Int64:
                return(Convert.ChangeType(value, targetType, CultureInfo.InvariantCulture));
            }

            string stringValue = ClientConvert.ToString(value);

            return(ClientConvert.ChangeType(stringValue, targetType));
        }