Dapper是否支持类似运营商?

时间:2011-05-17 11:28:04

标签: sql dapper

使用Dapper-dot-net ......

以下内容未在数据对象中产生结果:

var data = conn.Query(@"
    select top 25 
    Term as Label, 
    Type, 
    ID 
    from SearchTerms 
    WHERE Term like '%@T%'", 
    new { T = (string)term });

但是,当我只使用常规字符串格式时:

string QueryString = String.Format("select top 25 Term as Label, Type, ID from SearchTerms WHERE Term like '%{0}%'", term);
var data = conn.Query(QueryString);

我在集合中得到25行。 Dapper没有正确解析参数@T的结尾吗?

5 个答案:

答案 0 :(得分:60)

尝试:

term = "whateverterm";
var encodeForLike = term => term.Replace("[", "[[]").Replace("%", "[%]");

string term = "%" + encodeForLike(term) + "%";
var data = conn.Query(@"
   select top 25 
  Term as Label, 
  Type, 
  ID 
  from SearchTerms 
  WHERE Term like @term", 
  new { term });

对于类似运算符没有什么特别之处,你永远不希望你的params在字符串文字中,它们将无法工作,相反它们将被解释为字符串。

注意

强烈建议不要使用第二个代码段中的硬编码示例,除了sql注入的一个大问题外,它还会导致dapper泄漏。

警告

带有通配符的任何like匹配都不是SARGable,这意味着它很慢并且需要索引扫描。

答案 1 :(得分:24)

最好的方法是使用它在查询中添加concat函数,因为它在sql注入中保存,但是concat函数仅支持上面的sql 2012

string query = "SELECT * from country WHERE Name LIKE CONCAT('%',@name,'%');"
var results = connection.query<country>(query, new {name});

答案 2 :(得分:19)

是的。这个简单的解决方案每次都适用于我:

db.Query<Remitente>("SELECT * 
                     FROM Remitentes 
                     WHERE Nombre LIKE @n", new { n = "%" + nombre + "%" })
                   .ToList();

答案 3 :(得分:3)

Sam的回答并不适合我,所以在经过一些测试之后,我想出了SQLite CONCAT equivalent这似乎有效:

string sql = "SELECT * FROM myTable WHERE Name LIKE '%' || @NAME || '%'";
var data = IEnumerable data = conn.Query(sql, new { NAME = Name });

答案 4 :(得分:0)

为了离题,Sam 的回答,这里是我创建两个辅助方法的方法,以使用 LIKE 运算符使搜索更容易。

首先,创建一个用于生成参数化查询的方法,该方法使用 dynamic: ,但是在您想要静态类型而不是动态类型的许多情况下,应该更需要创建强类型泛型方法。

public static dynamic ParameterizedQuery(this IDbConnection connection, string sql, Dictionary<string, object> parametersDictionary)
{
    if (string.IsNullOrEmpty(sql))
    {
        return null;
    }
    string missingParameters = string.Empty;
    foreach (var item in parametersDictionary)
    {
        if (!sql.Contains(item.Key))
        {
            missingParameters += $"Missing parameter: {item.Key}";
        }
    }
    if (!string.IsNullOrEmpty(missingParameters))
    {
        throw new ArgumentException($"Parameterized query failed. {missingParameters}");
    }
    var parameters = new DynamicParameters(parametersDictionary);
    return connection.Query(sql, parameters);
}

然后添加一个方法来创建一个适用于 Dapper 的 Like 搜索词。

public static string Like(string searchTerm)
{
    if (string.IsNullOrEmpty(searchTerm))
    {
        return null;
    }
    Func<string, string> encodeForLike = searchTerm => searchTerm.Replace("[", "[[]").Replace("%", "[%]");
    return $"%{encodeForLike(searchTerm)}%";
}

示例用法:

var sql = $"select * from products where ProductName like @ProdName";
var herringsInNorthwindDb = connection.ParameterizedQuery(sql, new Dictionary<string, object> { { "@ProdName", Like("sild") } });

foreach (var herring in herringsInNorthwindDb)
{
    Console.WriteLine($"{herring.ProductName}");
}

我们从 Northwind DB 获取样本数据:
Sample data

我喜欢这种方法,因为我们使用辅助扩展方法来完成重复性工作。