コード例 #1
0
        private bool TryBindIdentifier(string identifier, IEnumerable <FunctionParameterToken> arguments, QueryNode parent, BindingState state, out QueryNode boundFunction)
        {
            boundFunction = null;

            IEdmType bindingType       = null;
            var      singleValueParent = parent as SingleValueNode;

            if (singleValueParent != null)
            {
                if (singleValueParent.TypeReference != null)
                {
                    bindingType = singleValueParent.TypeReference.Definition;
                }
            }
            else
            {
                var collectionValueParent = parent as CollectionNode;
                if (collectionValueParent != null)
                {
                    bindingType = collectionValueParent.CollectionType.Definition;
                }
            }

            if (!UriEdmHelpers.IsBindingTypeValid(bindingType))
            {
                return(false);
            }

            IEdmFunctionImport            functionImport;
            List <FunctionParameterToken> syntacticArguments = arguments == null ? new List <FunctionParameterToken>() : arguments.ToList();

            if (!FunctionOverloadResolver.ResolveFunctionsFromList(identifier, syntacticArguments.Select(ar => ar.ParameterName).ToList(), bindingType, state.Model, out functionImport))
            {
                return(false);
            }

            if (singleValueParent != null && singleValueParent.TypeReference == null)
            {
                // if the parent exists, but has no type information, then we're in open type land, and we
                // shouldn't go any farther.
                throw new ODataException(ODataErrorStrings.FunctionCallBinder_CallingFunctionOnOpenProperty(identifier));
            }

            if (functionImport.IsSideEffecting)
            {
                return(false);
            }

            ICollection <FunctionParameterToken> parsedParameters;

            if (!FunctionParameterParser.TryParseFunctionParameters(syntacticArguments, state.Configuration, functionImport, out parsedParameters))
            {
                return(false);
            }

            IEnumerable <QueryNode> boundArguments = parsedParameters.Select(p => this.bindMethod(p));

            IEdmTypeReference returnType = functionImport.ReturnType;
            IEdmEntitySet     returnSet  = null;
            var singleEntityNode         = parent as SingleEntityNode;

            if (singleEntityNode != null)
            {
                returnSet = functionImport.GetTargetEntitySet(singleEntityNode.EntitySet, state.Model);
            }

            if (returnType.IsEntity())
            {
                boundFunction = new SingleEntityFunctionCallNode(identifier, new[] { functionImport }, boundArguments, (IEdmEntityTypeReference)returnType.Definition.ToTypeReference(), returnSet, parent);
            }
            else if (returnType.IsEntityCollection())
            {
                IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType;
                boundFunction = new EntityCollectionFunctionCallNode(identifier, new[] { functionImport }, boundArguments, collectionTypeReference, returnSet, parent);
            }
            else if (returnType.IsCollection())
            {
                IEdmCollectionTypeReference collectionTypeReference = (IEdmCollectionTypeReference)returnType;
                boundFunction = new CollectionFunctionCallNode(identifier, new[] { functionImport }, boundArguments, collectionTypeReference, parent);
            }
            else
            {
                boundFunction = new SingleValueFunctionCallNode(identifier, new[] { functionImport }, boundArguments, returnType, parent);
            }

            return(true);
        }