private IEnumerable <ParameterDescriptor> GetParameters(MethodInfo method, StoreFunctionKind storeFunctionKind) { Debug.Assert(method != null, "method is null"); foreach (var parameter in method.GetParameters()) { if (method.IsDefined(typeof(ExtensionAttribute), false) && parameter.Position == 0) { continue; } if (parameter.IsOut || parameter.ParameterType.IsByRef) { throw new InvalidOperationException( $"The parameter '{parameter.Name}' of function '{method.Name}' is an out or ref parameter. To map Input/Output database parameters use the 'ObjectParameter' as the parameter type."); } var paramTypeAttribute = (ParameterTypeAttribute)Attribute.GetCustomAttribute(parameter, typeof(ParameterTypeAttribute)); var parameterType = parameter.ParameterType; var isObjectParameter = parameter.ParameterType == typeof(ObjectParameter); if (isObjectParameter) { if (paramTypeAttribute == null) { throw new InvalidOperationException( $"Cannot infer type for parameter '{parameter.Name}' of funtion '{method.Name}'. All ObjectParameter parameters must be decorated with the ParameterTypeAttribute."); } parameterType = paramTypeAttribute.Type; } var unwrappedParameterType = Nullable.GetUnderlyingType(parameterType) ?? parameterType; var parameterEdmType = unwrappedParameterType.IsEnum ? FindEnumType(unwrappedParameterType) : GetEdmPrimitiveTypeForClrType(unwrappedParameterType); if (parameterEdmType == null) { throw new InvalidOperationException( $"The type '{unwrappedParameterType.FullName}' of the parameter '{parameter.Name}' of function '{method.Name}' is invalid. Parameters can only be of a type that can be converted to an Edm scalar type"); } if (storeFunctionKind == StoreFunctionKind.ScalarUserDefinedFunction && parameterEdmType.BuiltInTypeKind != BuiltInTypeKind.PrimitiveType) { throw new InvalidOperationException( $"The parameter '{parameter.Name}' of function '{method.Name}' is of the '{parameterEdmType}' type which is not an Edm primitive type. Types of parameters of store scalar functions must be Edm primitive types."); } yield return(new ParameterDescriptor(parameter.Name, parameterEdmType, paramTypeAttribute != null ? paramTypeAttribute.StoreType : null, isObjectParameter)); } }
public FunctionDescriptor(string name, IEnumerable<ParameterDescriptor> parameters, EdmType[] returnTypes, string resultColumnName, string databaseSchema, StoreFunctionKind storeFunctionKind) { Debug.Assert(!string.IsNullOrWhiteSpace(name), "invalid name"); Debug.Assert(parameters != null, "parameters is null"); Debug.Assert(parameters.All(p => p.EdmType != null), "invalid parameter type"); Debug.Assert(returnTypes != null && returnTypes.Length > 0, "returnTypes array is null or empty"); Debug.Assert(storeFunctionKind == StoreFunctionKind.StoredProcedure|| returnTypes.Length == 1, "multiple return types for non-sproc"); _name = name; _returnTypes = returnTypes; _parameters = parameters.ToArray(); _resultColumnName = resultColumnName; _databaseSchema = databaseSchema; _storeFunctionKind = storeFunctionKind; }
public FunctionDescriptor(string name, IEnumerable <ParameterDescriptor> parameters, EdmType[] returnTypes, string resultColumnName, string databaseSchema, StoreFunctionKind storeFunctionKind) { Debug.Assert(!string.IsNullOrWhiteSpace(name), "invalid name"); Debug.Assert(parameters != null, "parameters is null"); Debug.Assert(parameters.All(p => p.EdmType != null), "invalid parameter type"); Debug.Assert(returnTypes != null && returnTypes.Length > 0, "returnTypes array is null or empty"); Debug.Assert(storeFunctionKind == StoreFunctionKind.StoredProcedure || returnTypes.Length == 1, "multiple return types for non-sproc"); _name = name; _returnTypes = returnTypes; _parameters = parameters.ToArray(); _resultColumnName = resultColumnName; _databaseSchema = databaseSchema; _storeFunctionKind = storeFunctionKind; }
private EdmType[] GetReturnTypes(string methodName, Type methodReturnType, DbFunctionDetailsAttribute functionDetailsAttribute, StoreFunctionKind storeFunctionKind) { Debug.Assert(methodReturnType != null, "methodReturnType is null"); var resultTypes = functionDetailsAttribute != null ? functionDetailsAttribute.ResultTypes : null; if (storeFunctionKind != StoreFunctionKind.StoredProcedure && resultTypes != null) { throw new InvalidOperationException( "The DbFunctionDetailsAttribute.ResultTypes property should be used only for stored procedures returning multiple resultsets and must be null for composable function imports."); } resultTypes = resultTypes == null || resultTypes.Length == 0 ? null : resultTypes; if (resultTypes != null && resultTypes[0] != methodReturnType) { throw new InvalidOperationException( string.Format( "The ObjectResult<T> item type returned by the method '{0}' is '{1}' but the first type specified in the `DbFunctionDetailsAttribute.ResultTypes` is '{2}'. The ObjectResult<T> item type must match the first type from the `DbFunctionDetailsAttribute.ResultTypes` array.", methodName, methodReturnType.FullName, resultTypes[0].FullName)); } var edmResultTypes = (resultTypes ?? new[] {methodReturnType}).Select(GetReturnEdmItemType).ToArray(); if (storeFunctionKind == StoreFunctionKind.ScalarUserDefinedFunction && edmResultTypes[0].BuiltInTypeKind != BuiltInTypeKind.PrimitiveType) { throw new InvalidOperationException( string.Format( "The type '{0}' returned by the method '{1}' cannot be mapped to an Edm primitive type. Scalar user defined functions have to return types that can be mapped to Edm primitive types.", methodReturnType.FullName, methodName)); } return edmResultTypes; }
private IEnumerable<ParameterDescriptor> GetParameters(MethodInfo method, StoreFunctionKind storeFunctionKind) { Debug.Assert(method != null, "method is null"); foreach (var parameter in method.GetParameters()) { if (method.IsDefined(typeof(ExtensionAttribute), false) && parameter.Position == 0) { continue; } if (parameter.IsOut || parameter.ParameterType.IsByRef) { throw new InvalidOperationException( string.Format( "The parameter '{0}' is an out or ref parameter. To map Input/Output database parameters use the 'ObjectParameter' as the parameter type.", parameter.Name)); } var parameterType = parameter.ParameterType; var isObjectParameter = parameter.ParameterType == typeof (ObjectParameter); if (isObjectParameter) { var paramType = (ParameterTypeAttribute)Attribute.GetCustomAttribute(parameter, typeof (ParameterTypeAttribute)); if (paramType == null) { throw new InvalidOperationException( string.Format( "Cannot infer type for parameter '{0}'. All ObjectParameter parameters must be decorated with the ParameterTypeAttribute.", parameter.Name)); } parameterType = paramType.Type; } var unwrappedParameterType = Nullable.GetUnderlyingType(parameterType) ?? parameterType; var parameterEdmType = unwrappedParameterType.IsEnum ? FindEnumType(unwrappedParameterType) : GetEdmPrimitiveTypeForClrType(unwrappedParameterType); if (parameterEdmType == null) { throw new InvalidOperationException( string.Format( "The type '{0}' of the parameter '{1}' of function '{2}' is invalid. Parameters can only be of a type that can be converted to an Edm scalar type", unwrappedParameterType.FullName, parameter.Name, method.Name)); } if (storeFunctionKind == StoreFunctionKind.ScalarUserDefinedFunction && parameterEdmType.BuiltInTypeKind != BuiltInTypeKind.PrimitiveType) { throw new InvalidOperationException( string.Format( "The parameter '{0}' is of the '{1}' type which is not an Edm primitive type. Types of parameters of store scalar functions must be Edm primitive types.", parameter.Name, parameterEdmType)); } yield return new ParameterDescriptor(parameter.Name, parameterEdmType, isObjectParameter); } }
private EdmType[] GetReturnTypes(string methodName, Type methodReturnType, DbFunctionDetailsAttribute functionDetailsAttribute, StoreFunctionKind storeFunctionKind) { Debug.Assert(methodReturnType != null, "methodReturnType is null"); var resultTypes = functionDetailsAttribute?.ResultTypes; if (storeFunctionKind != StoreFunctionKind.StoredProcedure && resultTypes != null) { throw new InvalidOperationException( $"The DbFunctionDetailsAttribute.ResultTypes property should be used only for stored procedures returning multiple resultsets and must be null for composable function imports. Function: '{methodName}'"); } resultTypes = resultTypes == null || resultTypes.Length == 0 ? null : resultTypes; if (resultTypes != null && resultTypes[0] != methodReturnType) { throw new InvalidOperationException( $"The ObjectResult<T> item type returned by the function '{methodName}' is '{methodReturnType.FullName}' but the first type specified in the `DbFunctionDetailsAttribute.ResultTypes` is '{resultTypes[0].FullName}'. The ObjectResult<T> item type must match the first type from the `DbFunctionDetailsAttribute.ResultTypes` array."); } var edmResultTypes = (resultTypes ?? new[] { methodReturnType }).Select(GetReturnEdmItemType).ToArray(); if (storeFunctionKind == StoreFunctionKind.ScalarUserDefinedFunction && edmResultTypes[0].BuiltInTypeKind != BuiltInTypeKind.PrimitiveType) { throw new InvalidOperationException( $"The type '{methodReturnType.FullName}' returned by the function '{methodName}' cannot be mapped to an Edm primitive type. Scalar user defined functions have to return types that can be mapped to Edm primitive types."); } return(edmResultTypes); }