示例#1
0
        private object ProcessNode(SingleValueQueryNode queryNode)
        {
            switch (queryNode.Kind)
            {
            case QueryNodeKind.Constant:
                return(ProcessConstant(queryNode as ConstantQueryNode));

            case QueryNodeKind.Convert:
                var convertNode = queryNode as ConvertQueryNode;
                var sourceValue = ProcessNode(convertNode.Source);
                if (convertNode.Source is ConstantQueryNode)
                {
                    if (convertNode.TargetType.IsInt32())
                    {
                        return(Convert.ToInt32(sourceValue));
                    }
                    if (convertNode.TargetType.IsString())
                    {
                        return(sourceValue.ToString());
                    }
                    if (convertNode.TargetType.IsDecimal())
                    {
                        return(Convert.ToDecimal(sourceValue));
                    }
                    throw new NotImplementedException("Haven't yet implemented convert to type " +
                                                      convertNode.TargetType);
                }
                return(sourceValue);

            case QueryNodeKind.BinaryOperator:
                var binaryOperatorNode = queryNode as BinaryOperatorQueryNode;
                return(BindOperator(binaryOperatorNode));

            case QueryNodeKind.UnaryOperator:
                var unaryOperatorNode = queryNode as UnaryOperatorQueryNode;
                return(BindOperator(unaryOperatorNode));

            case QueryNodeKind.PropertyAccess:
                return(ProcessNode(queryNode as PropertyAccessQueryNode));

            case QueryNodeKind.SingleValueFunctionCall:
                return(BindSingleValueFunctionCall(queryNode as SingleValueFunctionCallQueryNode));

            default:
                throw new NotImplementedException("No support for " + queryNode.Kind);
            }
        }
示例#2
0
        /// <summary>
        /// Checks if the source is of the specified type and if not tries to inject a convert.
        /// </summary>
        /// <param name="source">The source node to apply the convertion to.</param>
        /// <param name="targetTypeReference">The target primitive type.</param>
        /// <returns>The converted query node.</returns>
        private static SingleValueQueryNode ConvertToType(SingleValueQueryNode source, IEdmTypeReference targetTypeReference)
        {
            Debug.Assert(source != null, "source != null");
            Debug.Assert(targetTypeReference != null, "targetType != null");
            Debug.Assert(targetTypeReference.IsODataPrimitiveTypeKind(), "Can only convert primitive types.");

            if (source.TypeReference != null)
            {
                // TODO: Do we check this here or in the caller?
                Debug.Assert(source.TypeReference.IsODataPrimitiveTypeKind(), "Can only work on primitive types.");

                if (source.TypeReference.IsEquivalentTo(targetTypeReference))
                {
                    return source;
                }
                else
                {
                    if (!TypePromotionUtils.CanConvertTo(source.TypeReference, targetTypeReference))
                    {
                        throw new ODataException(Strings.MetadataBinder_CannotConvertToType(source.TypeReference.ODataFullName(), targetTypeReference.ODataFullName()));
                    }
                }
            }

            // If the source doesn't have a type (possibly an open property), then it's possible to convert it
            // cause we don't know for sure.
            return new ConvertQueryNode()
            {
                Source = source,
                TargetType = targetTypeReference
            };
        }
        private Expression Bind(QueryNode node)
        {
            CollectionQueryNode  collectionNode  = node as CollectionQueryNode;
            SingleValueQueryNode singleValueNode = node as SingleValueQueryNode;

            IncrementBindCount();

            if (collectionNode != null)
            {
                switch (node.Kind)
                {
                case QueryNodeKind.Filter:
                    return(BindFilterQueryNode(node as FilterQueryNode));

                case QueryNodeKind.Segment:
                    CollectionNavigationNode navigationNode = node as CollectionNavigationNode;
                    return(BindNavigationPropertyNode(navigationNode.Source, navigationNode.NavigationProperty()));

                default:
                    throw Error.NotSupported(SRResources.QueryNodeBindingNotSupported, node.Kind, typeof(FilterBinder).Name);
                }
            }
            else if (singleValueNode != null)
            {
                switch (node.Kind)
                {
                case QueryNodeKind.BinaryOperator:
                    return(BindBinaryOperatorQueryNode(node as BinaryOperatorQueryNode));

                case QueryNodeKind.Constant:
                    return(BindConstantQueryNode(node as ConstantQueryNode));

                case QueryNodeKind.Convert:
                    return(BindConvertQueryNode(node as ConvertQueryNode));

                case QueryNodeKind.Parameter:
                    return(BindParameterQueryNode(node as ParameterQueryNode));

                case QueryNodeKind.PropertyAccess:
                    return(BindPropertyAccessQueryNode(node as PropertyAccessQueryNode));

                case QueryNodeKind.UnaryOperator:
                    return(BindUnaryOperatorQueryNode(node as UnaryOperatorQueryNode));

                case QueryNodeKind.SingleValueFunctionCall:
                    return(BindSingleValueFunctionCallQueryNode(node as SingleValueFunctionCallQueryNode));

                case QueryNodeKind.Segment:
                    SingletonNavigationNode navigationNode = node as SingletonNavigationNode;
                    return(BindNavigationPropertyNode(navigationNode.Source, navigationNode.NavigationProperty));

                case QueryNodeKind.Any:
                    return(BindAnyQueryNode(node as AnyQueryNode));

                case QueryNodeKind.All:
                    return(BindAllQueryNode(node as AllQueryNode));

                default:
                    throw Error.NotSupported(SRResources.QueryNodeBindingNotSupported, node.Kind, typeof(FilterBinder).Name);
                }
            }
            else
            {
                throw Error.NotSupported(SRResources.QueryNodeBindingNotSupported, node.Kind, typeof(FilterBinder).Name);
            }
        }
示例#4
0
 private object ProcessNode(SingleValueQueryNode queryNode)
 {
     switch (queryNode.Kind)
     {
         case QueryNodeKind.Constant:
             return ProcessConstant(queryNode as ConstantQueryNode);
         case QueryNodeKind.Convert:
             var convertNode = queryNode as ConvertQueryNode;
             var sourceValue = ProcessNode(convertNode.Source);
             if (convertNode.Source is ConstantQueryNode)
             {
                 if (convertNode.TargetType.IsInt32())
                 {
                     return Convert.ToInt32(sourceValue);
                 }
                 if (convertNode.TargetType.IsString())
                 {
                     return sourceValue.ToString();
                 }
                 if (convertNode.TargetType.IsDecimal())
                 {
                     return Convert.ToDecimal(sourceValue);
                 }
                 throw new NotImplementedException("Haven't yet implemented convert to type " +
                                                   convertNode.TargetType);
             }
             return sourceValue;
         case QueryNodeKind.BinaryOperator:
             var binaryOperatorNode = queryNode as BinaryOperatorQueryNode;
             return BindOperator(binaryOperatorNode);
         case QueryNodeKind.UnaryOperator:
             var unaryOperatorNode = queryNode as UnaryOperatorQueryNode;
             return BindOperator(unaryOperatorNode);
         case QueryNodeKind.PropertyAccess:
             return ProcessNode(queryNode as PropertyAccessQueryNode);
         case QueryNodeKind.SingleValueFunctionCall:
             return BindSingleValueFunctionCall(queryNode as SingleValueFunctionCallQueryNode);
         default:
             throw new NotImplementedException("No support for " + queryNode.Kind);
     }
 }
示例#5
0
        /// <summary>
        /// Checks if the source is of the specified type and if not tries to inject a convert.
        /// </summary>
        /// <param name="source">The source node to apply the convertion to.</param>
        /// <param name="targetType">The target primitive resource type.</param>
        /// <returns>The converted query node.</returns>
        private SingleValueQueryNode ConvertToType(SingleValueQueryNode source, ResourceType targetType)
        {
            Debug.Assert(source != null, "source != null");
            Debug.Assert(targetType != null, "targetType != null");
            Debug.Assert(targetType.ResourceTypeKind == ResourceTypeKind.Primitive, "Can only convert primitive types.");

            if (source.ResourceType != null)
            {
                // TODO: Do we check this here or in the caller?
                Debug.Assert(source.ResourceType.ResourceTypeKind == ResourceTypeKind.Primitive, "Can only work on primitive types.");

                ResourceType sourceResourceType = this.metadataProvider.ValidateResourceType(source.ResourceType);

                // NOTE we have to also allow different resource types with the same name if they are primitive resource
                //      types since the resource types for 'bool' and 'bool?' have the same name.
                Debug.Assert(
                    sourceResourceType == targetType || 
                    sourceResourceType.FullName != targetType.FullName || 
                    sourceResourceType.ResourceTypeKind == ResourceTypeKind.Primitive && targetType.ResourceTypeKind == ResourceTypeKind.Primitive,
                    "The types were not atomized correctly.");

                if (this.ResourceTypesEqual(sourceResourceType, targetType))
                {
                    return source;
                }
                else
                {
                    if (!TypePromotionUtils.CanConvertTo(sourceResourceType.InstanceType, targetType.InstanceType))
                    {
                        throw new ODataException(Strings.MetadataBinder_CannotConvertToType(sourceResourceType.FullName, targetType.FullName));
                    }
                }
            }

            // If the source doesn't have a type (possibly an open property), then it's possible to convert it
            // cause we don't know for sure.
            return new ConvertQueryNode()
            {
                Source = source,
                TargetResourceType = targetType
            };
        }