[C#][MSSQL]SQL組字串Helper

  • 562
  • 0
  • C#
  • 2016-12-30

SQL組字串Helper

在SQL比較複雜的情況底下,用LINQ來寫並不是那麼容易,所以自己還是會寫到原生的SQL。  而當寫到原生的SQL時,就會有SQL組where條件字串與傳遞SqlParameter的需求,最近剛好寫了一個ClauseAssembler類別來處理這個需求。


ClauseAssembler用法:

string commandText = @"SELECT *
                         FROM Employee
                         {0}";

ClauseAssembler assembler = new ClauseAssembler();

assembler.Add<string>("WHERE Name LIKE '%' + @Name + '%'", "Miles");
assembler.Add<int>("AND Position = @Position", 3);

var clause = assembler.Output();

commandText = string.Format(commandText, clause.Item1);

var data = _db.Database.SqlQuery<Employee>(commandText, clause.Item2);

clause說明:

  • clause.Item1 : 拿來取代{0}的字串
  • clause.Item2 : @Name跟@Position的SqlParameter

產生的SQL如下:

SELECT * 
FROM Employee
WHERE Name LIKE '%'+@Name+'%'
AND Position = @Position

心得:這樣where條件字串跟SqlParameter一起寫,整個方便很多。

 

附上ClauseAssembler Source Code

/// <summary>
/// SQL條件組裝器
/// </summary>
public class ClauseAssembler
{
    public ClauseAssembler()
    {
        this.Clauses = new List<string>();
        this.Parameters = new List<SqlParameter>();
    }

    /// <summary>
    /// 組裝字串
    /// </summary>
    private List<string> Clauses { get; set; }

    /// <summary>
    /// 條件參數
    /// </summary>
    private List<SqlParameter> Parameters { get; set; }

    /// <summary>
    /// 新增clause
    /// </summary>
    /// <typeparam name="T">參數型別</typeparam>
    /// <param name="clause">查詢子句</param>
    /// <param name="value">參數值</param>
    /// <returns>Fluent ClauseAssembler</returns>
    public ClauseAssembler Add<T>(string clause, T value)
    {
        string removedSpaceClause = clause.Trim();
        this.Clauses.Add(removedSpaceClause);
        Regex regex = new Regex("@.*[a-zA-Z_]");
        Match match = regex.Match(removedSpaceClause);
        string argumentName = string.Empty;

        if (match.Success)
        {
            argumentName = match.Value;
        }

        SqlParameter parameter = new SqlParameter(argumentName, value);
        this.Parameters.Add(parameter);
        return this;
    }

    /// <summary>
    /// 新增clause
    /// </summary>
    /// <typeparam name="T">參數型別</typeparam>
    /// <param name="clause">查詢子句</param>        
    /// <returns>Fluent ClauseAssembler</returns>
    public ClauseAssembler Add(string clause)
    {
        string removedSpaceClause = clause.Trim();
        this.Clauses.Add(removedSpaceClause);
        return this;
    }

    /// <summary>
    /// 取得結果條件子句與SqlParameter
    /// </summary>
    /// <param name="isClear">是否清除clause</param>
    /// <returns>
    /// Item1:條件子句
    /// Item2:SqlParameter[]
    /// </returns>
    public Tuple<string, SqlParameter[]> Output(bool isClear = true)
    {
        string clause = string.Join(" ", this.Clauses);
        SqlParameter[] parameters = this.Parameters.ToArray();

        if (isClear)
        {
            this.Clauses.Clear();
            this.Parameters.Clear();
        }

        return Tuple.Create(clause, parameters);
    }
}

 

如果任何建議或問題歡迎留言討論

 

 

一天一分享,身體好健康。

該追究的不是過去的原因,而是現在的目的。