Exemplo n.º 1
0
        /// <summary>
        /// 获取代理方法信息
        /// </summary>
        /// <param name="method">方法</param>
        /// <param name="args">参数列表</param>
        /// <returns>SqlProxyMethod</returns>
        private SqlProxyMethod GetProxyMethod(MethodInfo method, object[] args)
        {
            // 判断方法是否贴了注解
            if (!method.IsDefined(typeof(SqlProxyAttribute), true))
            {
                throw Oops.Oh("The method is missing the [SqlProxy] annotation", typeof(InvalidOperationException));
            }

            // 获取 Sql 代理特性
            var sqlProxyAttribute = method.GetCustomAttribute <SqlProxyAttribute>(true);

            // 判断是否是异步方法
            var isAsyncMethod = method.IsAsync();

            // 获取类型返回值并处理 Task 和 Task<T> 类型返回值
            var returnType = method.ReturnType;

            returnType = isAsyncMethod ? (returnType.GenericTypeArguments.FirstOrDefault() ?? typeof(void)) : returnType;

            // 获取数据库上下文
            var dbContext = GetDbContext(sqlProxyAttribute.DbContextLocator);

            // 转换方法参数
            var parameters = method.GetParameters().ToSqlParameters(args);

            // 定义最终 Sql 语句
            string finalSql;
            var    commandType = CommandType.Text;

            // 如果是存储过程类型
            if (sqlProxyAttribute is SqlProduceAttribute sqlProduceAttribute)
            {
                finalSql    = sqlProduceAttribute.Name;
                commandType = CommandType.StoredProcedure;
            }
            // 如果是函数类型
            else if (sqlProxyAttribute is SqlFunctionAttribute sqlFunctionAttribute)
            {
                finalSql = DbHelpers.CombineFunctionSql(dbContext.Database.ProviderName,
                                                        returnType.IsRichPrimitive() ? DbFunctionType.Scalar : DbFunctionType.Table,
                                                        sqlFunctionAttribute.Name,
                                                        parameters);
            }
            // 如果是纯Sql类型
            else if (sqlProxyAttribute is SqlExecuteAttribute sqlExecuteAttribute)
            {
                finalSql    = sqlExecuteAttribute.Sql;
                commandType = sqlExecuteAttribute.CommandType;
            }
            else
            {
                throw Oops.Oh($"{sqlProxyAttribute.GetType().FullName} is an invalid annotation", typeof(NotSupportedException));
            }

            // 返回
            return(new SqlProxyMethod
            {
                SqlParameters = parameters,
                DbContext = dbContext,
                ReturnType = returnType,
                IsAsync = isAsyncMethod,
                CommandType = commandType,
                FinalSql = finalSql
            });
        }