示例#1
0
            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);
            }
示例#2
0
        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);
        }
示例#3
0
        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>()));
        }
示例#5
0
        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)));
        }