[Dapper] Get Output Value

 近來專案上遇到,預存程序有Output的情況,踩了一點雷,在這邊紀錄一下。

大致上的流程是要先建立一個DynamicParameters,將預存程序會用到的參數都篩進去,然後是Output的參數要特別處理(direction要給 ParameterDirection.Output),這樣在conn.Query()之後就可以在我們原先建立的DynamicParameters裡取得Output的值了。

ps:請注意在DynamicParameters.Add()的時候,若sql有限制參數大小 如:varchar(10),記得給size,且direction一定要給ParameterDirection.Output,否則可能會有Exception或者取回空值得情況發生。


範例:

1.先建立一個  DynamicParameters 產生器,來產生預存程序會用到的參數

 /// <summary>
    /// DynamicParameters-Builder
    /// </summary>
    public class DynamicParametersBuild
    {
        public DynamicParameters Data { get; set; }
        public DynamicParametersBuild(object data)
        {
            OriginalBuild(data);
        }
        /// <summary>
        ///  Original Build DynamicParameters
        /// </summary>
        /// <param name="data">data</param>
        private void OriginalBuild(object data)
        {
            var parameters = new DynamicParameters();
            var properties = data.GetType().GetProperties();
            foreach (var prop in properties)
            {
                var key = prop.Name;
                var value = prop.GetValue(data);
                parameters.Add(key, value);
            }
            this.Data = parameters;
        }
        /// <summary>
        /// Add a parameter to this dynamic parameter list.
        /// </summary>
        /// <param name="name">The name of the parameter.</param>
        /// <param name="value">The value of the parameter.</param>
        /// <param name="dbType">The type of the parameter.</param>
        /// <param name="direction">The in or out direction of the parameter.</param>
        /// <param name="size">The size of the parameter.</param>
        /// <param name="precision">The precision of the parameter.</param>
        /// <param name="scale">The scale of the parameter.</param>
        public void Add(string name, object value = null, DbType? dbType = null, ParameterDirection? direction = null, int? size = null, byte? precision = null, byte? scale = null)
        {
            Data.Add(name, value, dbType, direction, size, precision, scale);
        }
    }

2.建立一個SqlHelper 來取得預存程序的Output參數(ps:取得的Result會依照outputNames給的順序回傳結果)

 public static class SqlHelper
    {
        private static readonly string _connectString = "your connect string";
        /// <summary>
        /// Get Output
        /// </summary>
        /// <param name="spName">stored procedure's name</param>
        /// <param name="parameters">params</param>
        /// <param name="outputNames">output param Name</param>
        /// <returns></returns>
        public static IEnumerable<object> GetOutputData(string spName, DynamicParameters parameters, params string[] outputNames)
        {
            using (var conn = new SqlConnection(_connectString))
            {
                conn.Query(spName, parameters, commandType: CommandType.StoredProcedure);
                for (var i = 0; i < outputNames.Length; i++)
                {
                    var name = outputNames[i];
                    yield return parameters.Get<object>(name);
                }
            }
        }

    }

3.測試code


  var paramsData = new { A = "A", B = "B" };
            //建立動態參數
            var parameters = new DynamicParametersBuild(paramsData);
            //新增Output 參數(ps:若sql有限制參數大小 如:varchar(10),記得給size)
            parameters.Add("OutputA", dbType: DbType.String, size: 10, direction: ParameterDirection.Output);
            parameters.Add("OutputB", dbType: DbType.DateTime, direction: ParameterDirection.Output);
            //取得「OutputA」,「OutputB」的object(取得的Result會依照outputNames給的順序回傳結果)
            var result = SqlHelper.GetOutputData("MyStoredProcedure", parameters.Data, "OutputA", "OutputB").ToArray();
            //再將Result轉型即可
            var outputA = (string)result[0];
            var outputB = (string)result[1];

留言

這個網誌中的熱門文章

[Visual Studio]位於網際網路或是限制區域上 或是檔案上標有 web 字樣 所以無法處理該檔案。若希望處理這些檔案 請移除 web 字樣。

[IIS] IIS執行時,發生拒絕存取路徑 問題

[windows] xcopy 備份至 「網路磁碟機」