private static IList <FunctionParameter> GetStoreReturnParameters(DbModel model, MethodInfo methodInfo, FunctionAttribute functionAttribute) { if (methodInfo.ReturnParameter == null || (methodInfo.ReturnParameter.ParameterType == typeof(void) && functionAttribute.Type != FunctionType.StoredProcedure)) { throw new NotSupportedException(string.Format("The return type of {0} is not supported.", methodInfo.Name)); } var returnParameterAttribute = methodInfo.ReturnParameter.GetCustomAttribute <ParameterAttribute>(); //var returnTypeAttributes = methodInfo.GetCustomAttributes<ResultTypeAttribute>(); if (functionAttribute.Type == FunctionType.StoredProcedure || functionAttribute.Type == FunctionType.TableValuedFunction) { if (returnParameterAttribute != null) { throw new NotSupportedException(string.Format("ParameterAttribute for return value of method {0} is not supported.", methodInfo.Name)); } } if (functionAttribute.Type == FunctionType.StoredProcedure || methodInfo.ReturnType == typeof(void)) { //Stored Procedure return(new FunctionParameter[0]); //return new[] //{ // FunctionParameter.Create("ReturnType", PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.Int32), ParameterMode.ReturnValue) //}; } //if (returnTypeAttributes.Length > 0) // throw new NotSupportedException(string.Format("ResultTypeAttribute for method {0} is not supported.", methodInfo.Name)); if (functionAttribute.Type == FunctionType.TableValuedFunction) { //if (returnParameterAttribute != null) // throw new NotSupportedException(string.Format("ParameterAttribute for return value of method {0} is not supported.", methodInfo.Name)); /* * <CollectionType> * <RowType> * <Property Name="PersonID" Type="int" Nullable="false" /> * <Property Name="FirstName" Type="nvarchar" MaxLength="50" /> * <Property Name="LastName" Type="nvarchar" MaxLength="50" /> * <Property Name="JobTitle" Type="nvarchar" MaxLength="50" /> * <Property Name="BusinessEntityType" Type="nvarchar" MaxLength="50" /> * </RowType> * </CollectionType> */ // returnParameterInfo.ParameterType is IQueryable<T>. var storeReturnParameterClrType = methodInfo.ReturnParameter.ParameterType.GetGenericArguments().Single(); var modelReturnParameterStructuralType = GetModelStructualType(model, storeReturnParameterClrType, methodInfo); var modelReturnParameterComplexType = modelReturnParameterStructuralType as ComplexType; RowType storeReturnParameterRowType = null; if (modelReturnParameterComplexType != null) { storeReturnParameterRowType = RowType.Create( modelReturnParameterComplexType.Properties.Select(property => EdmProperty.Create(property.Name, model.ProviderManifest.GetStoreType(property.TypeUsage))), null); } else { var modelReturnParameterEntityType = modelReturnParameterStructuralType as EntityType; if (modelReturnParameterEntityType != null) { storeReturnParameterRowType = RowType.Create( modelReturnParameterEntityType.Properties.Select(property => CloneEdmProperty(property)), null); } else { throw new NotSupportedException(string.Format("Structural type {0} of method {1} cannot be converted to RowType.", modelReturnParameterStructuralType.FullName, methodInfo.Name)); } } return(new[] { FunctionParameter.Create( "ReturnType", storeReturnParameterRowType.GetCollectionType(), // Collection of RowType. ParameterMode.ReturnValue) }); } //if (functionAttribute.Type == FunctionType.NonComposableScalarValuedFunction) //{ // // Non-composable scalar-valued function. // return new FunctionParameter[0]; //} // Composable scalar-valued/Aggregate/Built in/Niladic function. // <Function Name="ufnGetProductListPrice" Aggregate="false" BuiltIn="false" NiladicFunction="false" IsComposable="true" ParameterTypeSemantics="AllowImplicitConversion" Schema="dbo" // ReturnType ="money"> var storeReturnParameterPrimitiveType = GetStoreParameterPrimitiveType(model, methodInfo, methodInfo.ReturnParameter, functionAttribute); return(new[] { FunctionParameter.Create("ReturnType", storeReturnParameterPrimitiveType, ParameterMode.ReturnValue) }); }
private static IList <FunctionParameter> GetStoreParameters(DbModel model, MethodInfo methodInfo, FunctionAttribute functionAttribute) { var parameters = GetDataParameters(methodInfo); if (parameters.Length > 0 && functionAttribute.Type == FunctionType.NiladicFunction) { throw new NotSupportedException(string.Format("The Niladic Function can not have parameter.", methodInfo.Name)); } var result = new List <FunctionParameter>(); for (int i = 0; i < parameters.Length; i++) { var parameterInfo = parameters[i]; var parameterAttrib = parameterInfo.GetCustomAttribute <ParameterAttribute>(); var parameterName = (parameterAttrib != null ? parameterAttrib.Name : null); if (string.IsNullOrWhiteSpace(parameterName)) { parameterName = parameterInfo.Name; } result.Add( FunctionParameter.Create( parameterName, GetStoreParameterPrimitiveType(model, methodInfo, parameterInfo, functionAttribute), (parameterInfo.IsOut || parameterInfo.ParameterType.IsByRef ? ParameterMode.InOut : ParameterMode.In))); } return(result.ToArray()); }
private static IList <FunctionParameter> GetModelReturnParameters(DbModel model, MethodInfo methodInfo, FunctionAttribute functionAttribute) { var returnParameterInfo = methodInfo.ReturnParameter; if (returnParameterInfo == null || (returnParameterInfo.ParameterType == typeof(void) && functionAttribute.Type != FunctionType.StoredProcedure)) { throw new NotSupportedException(string.Format("The return parameter type of {0} is not supported.", methodInfo.Name)); } var returnParameterAttribute = returnParameterInfo.GetCustomAttribute <ParameterAttribute>(); //var returnTypeAttributes = methodInfo.GetCustomAttributes<ResultTypeAttribute>(); IEnumerable <EdmType> modelReturnParameterEdmTypes; if (functionAttribute.Type == FunctionType.StoredProcedure) { if (returnParameterAttribute != null) { throw new NotSupportedException(string.Format("ParameterAttribute for method {0} is not supported.", methodInfo.Name)); } modelReturnParameterEdmTypes = GetStoredProcedureReturnTypes(methodInfo) .Select(clrType => GetModelStructualType(model, clrType, methodInfo)); } else { //if (returnTypeAttributes.Length > 0) //{ // throw new NotSupportedException( // string.Format("ResultTypeAttribute for method {0} is not supported.", methodInfo.Name)); //} if (functionAttribute.Type == FunctionType.TableValuedFunction) { // returnParameterInfo.ParameterType is IQueryable<T>. Type returnParameterClrType = returnParameterInfo.ParameterType.GetGenericArguments().Single(); StructuralType modelReturnParameterStructuralType = GetModelStructualType(model, returnParameterClrType, methodInfo); modelReturnParameterEdmTypes = Enumerable.Repeat(modelReturnParameterStructuralType, 1); } else { Type returnParameterClrType = returnParameterInfo.ParameterType; Type returnParameterAttributeClrType = (returnParameterAttribute != null ? returnParameterAttribute.ClrType : null); if (returnParameterAttributeClrType != null && returnParameterAttributeClrType != returnParameterClrType) { throw new NotSupportedException( string.Format("Return parameter of method {0} is of {1}, but its ParameterAttribute.ClrType has a different type {2}", methodInfo.Name, returnParameterClrType.FullName, returnParameterAttributeClrType.FullName)); } PrimitiveType returnParameterPrimitiveType = GetModelPrimitiveType(model, returnParameterClrType, methodInfo); modelReturnParameterEdmTypes = Enumerable.Repeat(returnParameterPrimitiveType, 1); } } return(modelReturnParameterEdmTypes .Select((edmType, index) => FunctionParameter.Create( string.Format("ReturnType{0}", index), edmType.GetCollectionType(), ParameterMode.ReturnValue)) .ToArray()); }
private static PrimitiveType GetStoreParameterPrimitiveType(DbModel model, MethodInfo methodInfo, ParameterInfo parameterInfo, FunctionAttribute functionAttribute) { var parameterClrType = parameterInfo.ParameterType; if (parameterClrType.IsByRef) { parameterClrType = parameterClrType.GetElementType(); } var parameterAttribute = parameterInfo.GetCustomAttribute <ParameterAttribute>(); //var parameterAttributeClrType = (parameterAttribute != null ? parameterAttribute.ClrType : null); if (parameterAttribute != null && parameterAttribute.ClrType != null) { parameterClrType = parameterAttribute.ClrType; } //if (parameterClrType.IsGenericType) //{ // var parameterClrTypeDefinition = parameterClrType.GetGenericTypeDefinition(); // if (parameterClrTypeDefinition == typeof(IEnumerable<>) || parameterClrTypeDefinition == typeof(IQueryable<>)) // { // //if (functionAttribute.Type == FunctionType.AggregateFunction) // // parameterClrType = parameterClrType.GetGenericArguments().Single(); // //else // throw new NotSupportedException( // string.Format("Parameter {0} of method {1} is not supported. {2} parameter must be used for FunctionType.AggregateFunction method.", // parameterInfo.Name, methodInfo.Name, typeof(IEnumerable<>).FullName)); // } //} //if (parameterClrType == typeof(ObjectParameter)) //{ // // ObjectParameter must be used for stored procedure parameter. // if (functionAttribute.Type != FunctionType.StoredProcedure) // { // throw new NotSupportedException( // string.Format("Parameter {0} of method {1} is not supported. ObjectParameter parameter must be used for FunctionType.StoredProcedure method.", // parameterInfo.Name, methodInfo.Name)); // } // // ObjectParameter.Type is available only when methodInfo is called. // // When building model, its store type/clr type must be provided by ParameterAttribute. // if (parameterAttributeClrType == null) // { // throw new NotSupportedException( // string.Format("Parameter {0} of method {1} is not supported. ObjectParameter parameter must have ParameterAttribute with ClrType specified, with optional DbType.", // parameterInfo.Name, methodInfo.Name)); // } // parameterClrType = parameterAttributeClrType; //} //else //{ // // When parameter is not ObjectParameter, ParameterAttribute.ClrType should be either not specified, or the same as parameterClrType. // if (parameterAttributeClrType != null && parameterAttributeClrType != parameterClrType) // { // throw new NotSupportedException( // string.Format("Parameter {0} of method {1} is not supported. It is of {2} type, but its ParameterAttribute.ClrType has a different type {3}", // parameterInfo.Name, methodInfo.Name, parameterClrType.FullName, parameterAttributeClrType.FullName)); // } //} var storePrimitiveTypeName = (parameterAttribute != null ? parameterAttribute.DbType : null); return(!string.IsNullOrEmpty(storePrimitiveTypeName) ? GetStorePrimitiveType(model, storePrimitiveTypeName, methodInfo, parameterInfo) : GetStorePrimitiveType(model, parameterClrType, methodInfo, parameterInfo)); }
private static IList <EntitySet> GetModelEntitySets(DbModel model, MethodInfo methodInfo, FunctionAttribute functionAttribute) { ParameterInfo returnParameterInfo = methodInfo.ReturnParameter; if (returnParameterInfo == null || (returnParameterInfo.ParameterType == typeof(void) && functionAttribute.Type != FunctionType.StoredProcedure)) { throw new NotSupportedException(string.Format("The return parameter type of {0} is not supported.", methodInfo.Name)); } if (returnParameterInfo.ParameterType == typeof(void)) { return(new EntitySet[0]); } else if (functionAttribute.Type == FunctionType.StoredProcedure && returnParameterInfo.ParameterType != typeof(void)) { //// returnParameterInfo.ParameterType is ObjectResult<T>. //var returnParameterClrTypes = GetStoredProcedureReturnTypes(methodInfo).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 => // { // var modelEntitySet = model // .ConceptualModel // .Container // .EntitySets // .FirstOrDefault(entitySet => entitySet.ElementType == GetModelEntityType(model, clrType, methodInfo)); // TODO: bug. // //if (modelEntitySet == null) // // throw new NotSupportedException( // // string.Format("{0} for method {1} is not supported in conceptual model as entity set.", clrType.FullName, methodInfo.Name)); // return modelEntitySet; // }).Where(s=>s!=null).ToArray(); //} } else if (functionAttribute.Type == FunctionType.TableValuedFunction) { // returnParameterInfo.ParameterType is IQueryable<T>. var returnParameterClrType = returnParameterInfo.ParameterType.GetGenericArguments().Single(); var returnParameterEntityType = GetModelEntityType(model, returnParameterClrType, methodInfo); if (returnParameterEntityType != null) { var modelEntitySet = model .ConceptualModel .Container .EntitySets .FirstOrDefault(entitySet => entitySet.ElementType == returnParameterEntityType); if (modelEntitySet == null) { throw new NotSupportedException( string.Format("{0} for method {1} is not supported in conceptual model as entity set.", returnParameterInfo.ParameterType.FullName, methodInfo.Name)); } return(new[] { modelEntitySet }); } } // Do not return new EntitySet[0], which causes a ArgumentException: // The number of entity sets should match the number of return parameters. return(null); }