[C#] 碰到 SQL IN 時,怎麼將陣列參數化?(to MODEL : Dapper + Slapper.AutoMapper)

How Can I Pass Dynamic Array To Sql Query In C#  by Dapper DynamicParameter

Parameterize an SQL IN clause by Dapper DynamicParameter

【寫 SQL 碰到 IN 就想自己組裝SQL嗎?你怎麼不害怕SQL Injection的悲慘世界?】

前言

 

基本介紹

開發環境

  1. Microsoft Visual Studio .NET 2017 Professional
  2. Oracle
  3. Dapper v2.0.30
  4. Slapper.AutoMapper v1.0.0.9

參考資料

  • (尚無)

常見作法

以下是我們常見的作法,

碰到 xxx IN ( 'a', 'b' ,'c' ) 這種需求的時候,最直接的方法就是…自己組裝SQL Statement。

string inClause = "";

//組裝SQL查詢子句
for (int i = 0; i < empIDList.Length; i++) 
{
   if (i > 0) 
   {
      inClause += ", ";
   }
   inClause += " '" + empIDList[0] + "' ";
}

//組合SQL語法
string cmdText = " SELECT * FROM empData WHERE deptID = :deptID AND empID IN (" + inClause + ") ";

//參數給值
parameter.Add(":deptID", deptID);

OracleCommand cmd = new OracleCommand(cmdText);

這種簡單粗暴的方法不是不行,但光是弱掃就會馬上被提示有SQL Injection的風險,

就不用說真的發生SQL Injection時的後果了.....

 

 

實作

由於Dapper有提供DynamicParameter的功能,

而且使用方式直接又簡單,幾乎完全不需要額外的思考,,,

以下方式示範了 Dapper + Slapper.AutoMapper 的實作方法

/// <summary>
/// 帶出員工資料
/// </summary>
/// <param name="deptID">部門代號</param>
/// <param name="empIDList">欲查詢的員工工號清單</param>
/// <returns></returns>
public List<empInfoModel> getEmpInfo(string deptID, List<string> empIDList)
{
    DynamicParameters parameter = new DynamicParameters();

    DataProviderBase db = new OracleDataProvider(connectionString);

    string select_cmd = @" SELECT * FROM empData WHERE deptID = :deptID AND empID IN (:empID) ";
    
    //原綁定參數的方法
    parameter.Add(":deptID", deptID);

    //Dapper綁定陣列參數的方式
    parameter.AddDynamicParams(new { empID = empIDList.ToArray() });

    //此處為使用 Dapper取回資料
    var tmpDM = db.GetDataModel<dynamic>(select_cmd, CommandType.Text, parameter);

    //此處透過Slapper.AutoMapper將資料填成model的資料結構
    var result = (Slapper.AutoMapper.MapDynamic<empInfoModel>(tmpDM)).ToList();

    return result;
}

 

 

 Written By Felix Hsieh