private void MapScalarFunction(DbFunctionAttribute dbfuncAttr) { var stringType = _model .ProviderManifest .GetStoreType( TypeUsage.CreateDefaultTypeUsage( PrimitiveType.GetEdmPrimitiveType(PrimitiveTypeKind.String))).EdmType; var edmParams = new List <FunctionParameter> { FunctionParameter.Create("inValue", stringType, ParameterMode.In) }; var edmReturnParams = new List <FunctionParameter> { FunctionParameter.Create("result", stringType, ParameterMode.ReturnValue) }; var functionPayload = new EdmFunctionPayload { StoreFunctionName = dbfuncAttr.FunctionName, Parameters = edmParams, ReturnParameters = edmReturnParams, Schema = "dbo" }; var function = EdmFunction.Create(dbfuncAttr.FunctionName, dbfuncAttr.NamespaceName, _model.StoreModel.DataSpace, functionPayload, null); _model.StoreModel.AddItem(function); }
private List <EdmFunction> CreateEdmFunctions(DbModel model) { Type type = this.GetFunctionType(); MethodInfo[] methods = type.GetMethods(); List <EdmFunction> edmFunctions = new List <EdmFunction>(); foreach (var method in methods) { DbFunctionAttribute dbFunction = method.GetCustomAttributes(false).OfType <DbFunctionAttribute>().FirstOrDefault(); if (dbFunction != null) { List <FunctionParameter> functionParameters = this.CreateFunctionParameters(method, model); FunctionParameter returnParameter = this.CreateReturnParameter(method, model); var functionPayload = new EdmFunctionPayload { Parameters = functionParameters.ToArray(), ReturnParameters = new List <FunctionParameter>() { returnParameter }.ToArray(), IsComposable = true, Schema = this.mNamespace, IsBuiltIn = false }; edmFunctions.Add(EdmFunction.Create(dbFunction.FunctionName, constant.Namespace, DataSpace.SSpace, functionPayload, null)); } } return(edmFunctions); }
public override DbExpression Visit(DbMethodCallExpression exp) { IMethodHandler methodHandler; if (MethodHandlers.TryGetValue(exp.Method.Name, out methodHandler)) { if (methodHandler.CanProcess(exp)) { methodHandler.Process(exp, this); return(exp); } } DbFunctionAttribute dbFunction = exp.Method.GetCustomAttribute <DbFunctionAttribute>(); if (dbFunction != null) { string schema = dbFunction.Schema; string functionName = string.IsNullOrEmpty(dbFunction.Name) ? exp.Method.Name : dbFunction.Name; if (!string.IsNullOrEmpty(schema)) { this.QuoteName(schema); this._sqlBuilder.Append("."); } this.QuoteName(functionName); this._sqlBuilder.Append("("); string c = ""; foreach (DbExpression argument in exp.Arguments) { this._sqlBuilder.Append(c); argument.Accept(this); c = ","; } this._sqlBuilder.Append(")"); return(exp); } if (exp.IsEvaluable()) { DbParameterExpression dbParameter = new DbParameterExpression(exp.Evaluate(), exp.Type); return(dbParameter.Accept(this)); } throw UtilExceptions.NotSupportedMethod(exp.Method); }
static EdmFunction CreateComposableEdmFunction([NotNull] MethodInfo method, [NotNull] DbFunctionAttribute dbFunctionInfo) { if (method == null) { throw new ArgumentNullException(nameof(method)); } if (dbFunctionInfo == null) { throw new ArgumentNullException(nameof(dbFunctionInfo)); } return(EdmFunction.Create( dbFunctionInfo.FunctionName, dbFunctionInfo.NamespaceName, DataSpace.SSpace, new EdmFunctionPayload { ParameterTypeSemantics = ParameterTypeSemantics.AllowImplicitConversion, Schema = string.Empty, IsBuiltIn = true, IsAggregate = false, IsFromProviderManifest = true, StoreFunctionName = dbFunctionInfo.FunctionName, IsComposable = true, ReturnParameters = new[] { FunctionParameter.Create( "ReturnType", MapTypeToEdmType(method.ReturnType), ParameterMode.ReturnValue) }, Parameters = method.GetParameters().Select( x => FunctionParameter.Create( x.Name, MapTypeToEdmType(x.ParameterType), ParameterMode.In)).ToList() }, new List <MetadataProperty>())); }
private FunctionDescriptor BuildFunctionDescriptor(MethodInfo mi) { DbFunctionAttribute attrFunction = mi.GetCustomAttribute <DbFunctionAttribute>(); if (attrFunction == null) { throw new InvalidOperationException(string.Format("Method {0} of type {1} must be marked by'DbFunction...' attribute.", mi.Name, mi.DeclaringType)); } DbFunctionExAttribute attrFunctionEx = attrFunction as DbFunctionExAttribute; string methodName = mi.Name; string functionName = !string.IsNullOrWhiteSpace(attrFunction.FunctionName) ? attrFunction.FunctionName : methodName; string databaseSchema = attrFunctionEx != null && !string.IsNullOrWhiteSpace(attrFunctionEx.Schema) ? attrFunctionEx.Schema : _databaseSchema; if (string.IsNullOrWhiteSpace(databaseSchema)) { throw new InvalidOperationException(string.Format("Database schema for method {0} of type {1} is not defined.", mi.Name, mi.DeclaringType)); } // bool isExtension = mi.IsDefined(typeof(ExtensionAttribute), false); ParameterDescriptor[] parameters = mi.GetParameters() .SkipWhile(pi => isExtension && pi.Position == 0 && pi.ParameterType.IsAssignableFrom(typeof(DbContext))) .OrderBy(pi => pi.Position) .Select((pi, i) => { FunctionParameterAttribute parameterAttr = pi.GetCustomAttribute <FunctionParameterAttribute>(); Type parameterType = pi.ParameterType == typeof(ObjectParameter) ? parameterAttr.Type : pi.ParameterType; if (parameterType == null) { throw new InvalidOperationException(string.Format("Method parameter '{0}' at position {1} is not defined.", pi.Name, pi.Position)); } // MinLengthAttribute minLengthAttr = pi.GetCustomAttribute <MinLengthAttribute>(); MaxLengthAttribute maxLengthAttr = pi.GetCustomAttribute <MaxLengthAttribute>(); FixedLengthAttribute fixedLengthAttr = pi.GetCustomAttribute <FixedLengthAttribute>(); PrecisionScaleAttribute precisionScaleAttr = pi.GetCustomAttribute <PrecisionScaleAttribute>(); // return(new ParameterDescriptor(i, parameterType.IsByRef ? pi.IsOut ? ParameterDirection.Output : ParameterDirection.InputOutput : ParameterDirection.Input, parameterType) { Name = parameterAttr != null && !string.IsNullOrWhiteSpace(parameterAttr.Name) ? parameterAttr.Name : pi.Name, StoreTypeName = parameterAttr != null && !string.IsNullOrWhiteSpace(parameterAttr.TypeName) ? parameterAttr.TypeName : null, Length = maxLengthAttr != null ? maxLengthAttr.Length : default(int?), IsFixedLength = minLengthAttr != null && maxLengthAttr != null ? minLengthAttr.Length == maxLengthAttr.Length : fixedLengthAttr != null ? fixedLengthAttr.IsFixedLength : default(bool?), Precision = precisionScaleAttr != null ? precisionScaleAttr.Precision : default(byte?), Scale = precisionScaleAttr != null ? precisionScaleAttr.Scale : default(byte?) }); }) .ToArray(); // IQueryable<> Type returnType = mi.ReturnType.IsGenericType && mi.ReturnType.GetGenericTypeDefinition() == typeof(IQueryable <>) ? mi.ReturnType : mi.ReturnType.GetInterfaces().SingleOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IQueryable <>)); if (returnType != null) { FunctionResultAttribute attrResult = mi.ReturnParameter.GetCustomAttribute <FunctionResultAttribute>(); ResultDescriptor result = new ResultDescriptor(returnType.GetGenericArguments()[0]) { ColumnName = attrResult != null ? attrResult.ColumnName : _resultColumnName, StoreTypeName = attrResult != null ? attrResult.TypeName : null }; return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, true, attrFunctionEx != null ? attrFunctionEx.IsComposable : default(bool?), isExtension ? attrFunctionEx != null ? attrFunctionEx.IsBuiltIn : default(bool?) : false, false, parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, Enumerable.Repeat(result, 1))); } // IQueryable returnType = mi.ReturnType == typeof(IQueryable) ? mi.ReturnType : mi.ReturnType.GetInterfaces().SingleOrDefault(t => t == typeof(IQueryable)); if (returnType != null) { FunctionResultAttribute attrResult = mi.ReturnParameter.GetCustomAttribute <FunctionResultAttribute>(); if (attrResult != null) { ResultDescriptor result = new ResultDescriptor(attrResult.Type) { ColumnName = attrResult.ColumnName ?? _resultColumnName, StoreTypeName = attrResult.TypeName }; return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, true, attrFunctionEx != null ? attrFunctionEx.IsComposable : default(bool?), isExtension ? attrFunctionEx != null ? attrFunctionEx.IsBuiltIn : default(bool?) : false, false, parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, Enumerable.Repeat(result, 1))); } throw new InvalidOperationException("Result type is not specified in function"); } // IEnumerable<> returnType = mi.ReturnType == typeof(string) || mi.ReturnType == typeof(byte[]) ? null : mi.ReturnType.IsGenericType && mi.ReturnType.GetGenericTypeDefinition() == typeof(IEnumerable <>) ? mi.ReturnType : mi.ReturnType.GetInterfaces().SingleOrDefault(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable <>)); if (returnType != null) { FunctionResultAttribute attrResult = mi.ReturnParameter.GetCustomAttribute <FunctionResultAttribute>(); IEnumerable <ResultDescriptor> results = Enumerable.Repeat(new ResultDescriptor(returnType.GetGenericArguments()[0]) { ColumnName = attrResult != null ? attrResult.ColumnName : _resultColumnName, StoreTypeName = attrResult != null ? attrResult.TypeName : null }, 1) .Concat(mi.GetCustomAttributes <FunctionResultAttribute>() .Select(a => new ResultDescriptor(a.Type) { ColumnName = a.ColumnName ?? _resultColumnName, StoreTypeName = a.TypeName })); return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, true, false, false, false, parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, results)); } // IEnumerable returnType = mi.ReturnType == typeof(string) || mi.ReturnType == typeof(byte[]) ? null : mi.ReturnType == typeof(IEnumerable) ? mi.ReturnType : mi.ReturnType.GetInterfaces().SingleOrDefault(t => t == typeof(IEnumerable)); if (returnType != null) { IEnumerable <ResultDescriptor> results = mi.GetCustomAttributes <FunctionResultAttribute>() .Select(a => new ResultDescriptor(a.Type) { ColumnName = a.ColumnName ?? _resultColumnName, StoreTypeName = a.TypeName }); return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, true, false, false, false, parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, results)); } // Scalar result returnType = mi.ReturnType; FunctionResultAttribute attr = mi.ReturnParameter.GetCustomAttribute <FunctionResultAttribute>(); ResultDescriptor resultDescriptor = new ResultDescriptor(mi.ReturnType) { StoreTypeName = attr != null ? attr.TypeName : null }; return(new FunctionDescriptor(_namespaceName, databaseSchema, functionName, false, attrFunctionEx != null ? attrFunctionEx.IsComposable : default(bool?), isExtension ? attrFunctionEx != null ? attrFunctionEx.IsBuiltIn : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.IsAggregate : default(bool?), parameters.Length == 0 ? attrFunctionEx != null ? attrFunctionEx.IsNiladic : default(bool?) : false, attrFunctionEx != null ? attrFunctionEx.ParameterTypeSemantics : default(ParameterTypeSemantics?), parameters, Enumerable.Repeat(resultDescriptor, 1))); }