這次遇到的是一個交易系統,客戶那邊負責撰寫stored procedure (SP),
雙方在進行第一次測試前,溝通只有靠規格文件,測試一定要到客戶端,
因為資料庫是封閉系統,所以在開發階段時,也得對規格文件模擬出
客戶端的狀況,但是假的SP不可能完全呈現真實的狀況,
所以前幾次到現場測試時,可以用災難來形容,
數百個SP,雙方各是幾萬行的程式,抓bug起來真的會哭,
當然一定會出現雙方各執一詞的狀況,系統串接一定會這樣,
雖然我們有用AOP來注入所有程式,記錄所有的副程式傳入跟傳出值,
但是一個商業邏輯的進行,通常不會只呼叫一個SP,舉例來說,
進行交易時,要做銀行帳戶檢查,金額檢查等等的.
我當然不可能為了一個SP就多寫一個副程式來呼叫,
這樣除錯會除到生氣.
情境是這樣,在呼叫SP時失敗了,雙方都說自己是對的,
那就是紀錄傳到客戶端的資料,請客戶的工程師拿這份資料去跑一次,
我用的ORM引擎是Dapper,呼叫SP使用Dapper.DynamicParameters,
所以只好在Dapper對資料庫下Query時,將所有資料記錄下來,
下中斷點就可以知道Dapper在哪裡下Query,
然後遇到的問題是Dapper的Dynamic Parameters怎麼方便轉成JSon的方式
(用JSon來做Log是很方便的)
請看程式碼,照抄還是會遇到麻煩,還是要好好理解,(Nlog使用方法請Google)
1: Logger logger = NLog.LogManager.GetCurrentClassLogger(); //NLog紀錄Log
2:
3: var parameters = (DynamicParameters)param;
4: var list = new Dictionary<string, string>();
5:
6: foreach (var paramName in parameters.ParameterNames)
7: {
8:
9: var value = Convert.ToString( parameters.Get<dynamic>(paramName));
10:
11: list.Add( paramName, value);
12: }
13:
14: logger.Info("SP Name::" + sql + Environment.NewLine + list.ToJSON());
首先Dapper的Query method傳入是 object param,這段程式碼等到上線時是要移掉的,
所以先將轉型成DynamicParameters,而他的屬性ParameterNames是個集合,
就跑foreach使用 DynamicParameters.Get<T>(ParamName)的方式來取值,
那就有Key跟Value了,將他存到Dictionary進去,ToJson是個Extension ,
這個很好查.如此就可以達成需求了.