[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];
留言
張貼留言