コード例 #1
0
        private static IList<EntitySet> GetModelEntitySets(this DbModel model, MethodInfo methodInfo, FunctionAttribute functionAttribute)
        {
            ParameterInfo returnParameterInfo = methodInfo.ReturnParameter;
            if (returnParameterInfo == null || returnParameterInfo.ParameterType == typeof(void))
            {
                throw new NotSupportedException($"The return parameter type of {methodInfo.Name} is not supported.");
            }

            if (functionAttribute.Type == FunctionType.StoredProcedure
                && returnParameterInfo.ParameterType != typeof(int))
            {
                // returnParameterInfo.ParameterType is ObjectResult<T>.
                Type[] returnParameterClrTypes = methodInfo.GetStoredProcedureReturnTypes().ToArray();
                if (returnParameterClrTypes.Length > 1)
                {
                    // Stored procedure has more than one result. 
                    // EdmFunctionPayload.EntitySets must be provided. Otherwise, an ArgumentException will be thrown:
                    // The EntitySets parameter must not be null for functions that return multiple result sets.
                    return returnParameterClrTypes.Select(clrType =>
                    {
                        EntitySet modelEntitySet = model
                            .ConceptualModel
                            .Container
                            .EntitySets
                            .FirstOrDefault(entitySet =>
                                entitySet.ElementType.FullName.EqualsOrdinal(clrType.FullName));
                        if (modelEntitySet == null)
                        {
                            throw new NotSupportedException(
                                $"{clrType.FullName} for method {methodInfo.Name} is not supported in conceptual model as entity set.");
                        }

                        return modelEntitySet;
                    }).ToArray();
                }
            }

            // Do not return new EntitySet[0], which causes a ArgumentException:
            // The number of entity sets should match the number of return parameters.
            return null;
        }
コード例 #2
0
        private static IList<FunctionParameter> GetModelReturnParameters(
            this DbModel model, MethodInfo methodInfo, FunctionAttribute functionAttribute)
        {
            ParameterInfo returnParameterInfo = methodInfo.ReturnParameter;
            if (returnParameterInfo == null || returnParameterInfo.ParameterType == typeof(void))
            {
                throw new NotSupportedException($"The return parameter type of {methodInfo.Name} is not supported.");
            }

            ParameterAttribute returnParameterAttribute = returnParameterInfo.GetCustomAttribute<ParameterAttribute>();
            ResultTypeAttribute[] returnTypeAttributes = methodInfo.GetCustomAttributes<ResultTypeAttribute>().ToArray();
            IEnumerable<EdmType> modelReturnParameterEdmTypes;
            if (functionAttribute.Type == FunctionType.StoredProcedure)
            {
                if (returnParameterAttribute != null)
                {
                    throw new NotSupportedException(
                        $"{nameof(ParameterAttribute)} for method {methodInfo.Name} is not supported.");
                }

                modelReturnParameterEdmTypes = methodInfo
                    .GetStoredProcedureReturnTypes()
                    .Select(clrType => model.GetModelStructualType(clrType, methodInfo));
            }
            else
            {
                if (returnTypeAttributes.Any())
                {
                    throw new NotSupportedException(
                        $"{nameof(ResultTypeAttribute)} for method {methodInfo.Name} is not supported.");
                }

                if (functionAttribute.Type == FunctionType.TableValuedFunction)
                {
                    // returnParameterInfo.ParameterType is IQueryable<T>.
                    Type returnParameterClrType = returnParameterInfo.ParameterType.GetGenericArguments().Single();
                    StructuralType modelReturnParameterStructuralType = model.GetModelStructualType(
                        returnParameterClrType, methodInfo);
                    modelReturnParameterEdmTypes = Enumerable.Repeat(modelReturnParameterStructuralType, 1);
                }
                else
                {
                    Type returnParameterClrType = returnParameterInfo.ParameterType;
                    Type returnParameterAttributeClrType = returnParameterAttribute?.ClrType;
                    if (returnParameterAttributeClrType != null
                        && returnParameterAttributeClrType != returnParameterClrType)
                    {
                        throw new NotSupportedException(
                            $"Return parameter of method {methodInfo.Name} is of {returnParameterClrType.FullName}, but its {nameof(ParameterAttribute)}.{nameof(ParameterAttribute.ClrType)} has a fifferent type {returnParameterAttributeClrType.FullName}");
                    }

                    PrimitiveType returnParameterPrimitiveType = model.GetModelPrimitiveType(
                        returnParameterClrType, methodInfo);
                    modelReturnParameterEdmTypes = Enumerable.Repeat(returnParameterPrimitiveType, 1);
                }
            }

            return modelReturnParameterEdmTypes
                .Select((edmType, index) => FunctionParameter.Create(
                    $"ReturnType{index}",
                    edmType.GetCollectionType(),
                    ParameterMode.ReturnValue))
                .ToArray();
        }