1.前言 上篇 寫出易調試的SQL , 帶來了一些討論, 暴露了不能重用執行計劃和sql註入問題, 十分感謝園友們的建議 . 經過調整後 ,將原來的SQLHelper 抓SQL 用做調試環境用, 發佈環境還是走Dapper的參數化查詢, 保持原有優勢. 見如下代碼. 2. 在開發調試階段 抓最終SQ ...
1.前言
上篇 寫出易調試的SQL , 帶來了一些討論, 暴露了不能重用執行計劃和sql註入問題, 十分感謝園友們的建議 .
經過調整後 ,將原來的SQLHelper 抓SQL 用做調試環境用, 發佈環境還是走Dapper的參數化查詢, 保持原有優勢.
見如下代碼.
2. 在開發調試階段 抓最終SQL
將Dapper 查詢Query 和執行Execute 進行了再包裝, 插入了 抓最終sql 的代碼
public class DapperTaller { /// <summary> /// dapper 執行查詢 sql /// </summary> /// <typeparam name="T"></typeparam> /// <param name="sql"></param> /// <param name="param"></param> /// <returns></returns> public static IEnumerable<T> Query<T>(string sql, object param) { IEnumerable<T> result = null; using (var con = DBHelper.GetConnection()) { result = con.Query<T>(sql, param); } //開發環境代碼 if (GlobalVariable.env.IsDevelopment()) //IsDevelopment 方法為Asp.NET Core 自帶的 是否為開發環境的判斷方法 { //最終SQL var debugSql = GetDebugSQL(sql, param); Debug.WriteLine(debugSql); } return result; } /// <summary> /// dapper 執行 增加, 刪除 ,修改 sql /// </summary> /// <param name="sql"></param> /// <param name="param"></param> /// <returns></returns> public static int Execute(string sql, object param) { int result; using (var con = DBHelper.GetConnection()) { result = con.Execute(sql, param); } //開發環境代碼 if (GlobalVariable.env.IsDevelopment()) //IsDevelopment 方法為Asp.NET Core 自帶的 是否為開發環境的判斷方法 { //最終SQL var debugSql = GetDebugSQL(sql, param); Debug.WriteLine(debugSql); } //生產環境代碼 if (GlobalVariable.env.IsProduction()) { //根據需要將最終SQL 記錄到日誌 } return result; } public static string GetDebugSQL(string sql, object param) { var sqlHelper = new SqlHelper(); foreach (var item in param.GetType().GetProperties()) { var name = item.Name; var value = item.GetValue(param); sqlHelper.Param.Add(name, value); } sqlHelper.ReplaceParam(ref sql); return sql; } } public class DBHelper { public static IDbConnection GetConnection() { return SQLServerHelper.GetConnection(); } }
調用代碼:
public IEnumerable<Ptype> GetPtypeDetail() { var sql = @" SELECT * FROM dbo.CoacherStudentMoney a INNER JOIN dbo.BaseData b ON a.CourseTypeId=b.Id WHERE StudentUserId=@StudentUserId AND Amount=@Amount AND IsPay=@IsPay AND CreateDate=@CreateDate "; var param = new { StudentUserId = "001", CreateDate = DateTime.Now, Amount = 3, IsPay = true }; IEnumerable<Ptype> plist = new List<Ptype>(); plist = DapperTaller.Query<Ptype>(sql, param); return plist; }
最上面代碼的此處為最終SQL 抓取
//開發環境代碼 if (GlobalVariable.env.IsDevelopment()) { //最終SQL var debugSql = GetDebugSQL(sql, param); Debug.WriteLine(debugSql); }
並且會在VS 的輸出視窗輸出
進一步方便了調試.
3.最後
現在最終SQL 的抓取發生在 調試開發階段 .
發佈代碼後, 將不會進行最終SQL的抓取. 並且走的還是Dapper 原有參數化查詢的方式, 依舊擁有執行計劃重用, 防SQL註入的優勢.
註:
完整可執行代碼見: https://pan.baidu.com/s/1jI4YcQi
本文代碼是 AnuoApc.Data 項目下的 -> Dapper目錄下的 -> DapperTaller.cs 文件, 可從這裡開始看
作者: 蔣奎
博客: http://www.cnblogs.com/anuo/
歡迎轉載,請在明顯位置給出出處及鏈接