簡體   English   中英

如何使用 dapper 構建動態參數化查詢?

[英]How to build dynamic parameterised query using dapper?

如何使用 dapper 構建動態參數化查詢?

我在 KeyValuePair 中有列及其值

例如

Key   | Value
------| -------
FName | Mohan
LName | O'reily
Gender| Male

我想使用 dapper 構建動態 SQL 語句並執行它,

    string statement = "SELECT * FROM Employee WHERE 1 = 1 ";
    List<KeyValuePair<string,string>> lst = new List<KeyValuePair<string,string>>();
    lst.Add(new KeyValuePair<string,String>("FName","Kim"));
    lst.Add(new KeyValuePair<string,String>("LName","O'reily"));
    lst.Add(new KeyValuePair<string,String>("Gender","Male"));
    foreach(var kvp in lst)
    {
        statement += " AND "+ kvp.Key +" = '"+ kvp.Value +"'";
    }
    using (var connection = _dataAccessHelper.GetOpenConnection())
    {
      try
      {
           //CommandDefinition cmd = new CommandDefinition(statement);

           var searchResult = await connection.QueryAsync<dynamic>(statement);

上述查詢失敗,因為查詢中有特殊字符。
我發現可以使用參數化語句CommandDefinition

如何使用CommandDefinition執行上述語句而沒有任何錯誤?
或者
有沒有更好的方法來構建動態sql語句?

不要將查詢構建為文本。 您可以使用 Dapper SqlBuilder,它是這樣的:

List<KeyValuePair<string,string>> lst = new List<KeyValuePair<string,string>>();
lst.Add(new KeyValuePair<string,String>("FName","Kim"));
lst.Add(new KeyValuePair<string,String>("LName","O'reily"));
lst.Add(new KeyValuePair<string,String>("Gender","Male"));
var builder = new SqlBuilder();
var select = builder.AddTemplate("select * from Employee /**where**/");
foreach (var kvPair in lst)
{
    builder.Where($"{kvPair.Key} = @{kvPair.Key}", new { kvPair.Value });
}
using (var connection = _dataAccessHelper.GetOpenConnection())
{
    try
    {
        var searchResult = await connection.QueryAsync<dynamic>(select.RawSql, select.Parameters);
    }
    ...

你永遠不應該試圖自己轉義參數,把它留給 Dapper。 然后,您還將受到保護,免受 SQL 注入的影響。

DapperQueryBuilder是 Dapper SqlBuilder 的替代品,其工作方式如下:

List<KeyValuePair<string,string>> lst = new List<KeyValuePair<string,string>>();
lst.Add(new KeyValuePair<string,String>("FName","Kim"));
lst.Add(new KeyValuePair<string,String>("LName","O'reily"));
lst.Add(new KeyValuePair<string,String>("Gender","Male"));

using (var connection = _dataAccessHelper.GetOpenConnection())
{
    var query = connection.QueryBuilder($@"SELECT * FROM Employee");

    foreach(var kvp in lst)
        query.Where(${kvp.Key:raw} = {kvp.Value}";

    var searchResult = await query.QueryAsync<YourPOCO>();
}

輸出是完全參數化的 SQL( WHERE FName = @p0 AND LName = @p1 etc )。

您只需要注意使用raw修飾符插入的字符串不會作為參數傳遞(因為您不能將列作為參數傳遞),因此您應該確保“鍵”(列名稱)是安全的。 其他字符串(在您的情況下為值)看起來像常規(不安全)字符串插值,但它們被轉換為參數。

免責聲明:我是這個庫的作者之一

沒有理由使用鍵值對列表來構建帶有動態參數的 SQL 語句。 您可以簡單地將占位符放在查詢中,例如上面示例中的@FName ,並通過將匿名類型及其與占位符對應的鍵和值傳遞給動態來提供這些占位符的值作為 QueryAsync 方法的第二個參數要用於查詢的值。

string statement = "SELECT * FROM Employee WHERE FName=@FName AND LName=@LName AND Gender=@Gender";
...
var searchResult = await connection.QueryAsync<dynamic>(statement, new { FName = "Kim", LName = "O'reily", Gender="Male" });

您可以將DynamicParameters類用於泛型字段。

Dictionary<string, object> Filters = new Dictionary<string, object>();
Filters.Add("UserName", "admin");
Filters.Add("Email", "admin@admin.com");
var builder = new SqlBuilder();
var select = builder.AddTemplate("select * from SomeTable /**where**/");
var parameter = new DynamicParameters();
foreach (var filter in Filters)
{
    parameter.Add(filter.Key, filter.Value);
    builder.Where($"{filter.Key} = @{filter.Key}");                        
}


var searchResult = appCon.Query<ApplicationUser>(select.RawSql, parameter);

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM