【问题标题】:String.Format with SQL wildcard causing Dapper query to break带有 SQL 通配符的 String.Format 导致 Dapper 查询中断
【发布时间】:2013-05-24 15:07:41
【问题描述】:

我在使用 Dapper 和字符串格式时遇到了一些奇怪的问题。以下是相关代码:

string end_wildcard = @"
SELECT * FROM users
WHERE (first_name LIKE CONCAT(@search_term, '%') OR last_name LIKE CONCAT(@search_term, '%'));";

string both_wildcards = @"
SELECT * FROM users
WHERE (first_name LIKE CONCAT('%', @search_term, '%') OR last_name LIKE CONCAT('%', @search_term, '%'));";

string formatted = @"
SELECT * FROM users
WHERE (first_name LIKE {0} OR last_name LIKE {0});";

string use_end_only = @"CONCAT(@search_term, '%')";
string use_both = @"CONCAT('%', @search_term, '%')";

// if true, slower query due to not being able to use indices, but will allow searching inside strings 
bool allow_start_wildcards = false; 

string query = String.Format(formatted, allow_start_wildcards ? use_both : use_end_only);
string term = "blah"; // the term the user searched for

// Using Dapper
db.Query(end_wildcard, new{ search_term = term}); // Works and returns results
db.Query(both_wildcards, new{ search_term = term}); // Works and returns results
db.Query(query, new{ search_term = term}); // Returns nothing

前两个查询,其中带有通配符的 CONCAT 语句被烘焙到字符串中,运行良好。但是,如果我取出 CONCAT 语句并使用 String.Format 注入一个或另一个,我得到 0 个结果。

其中最奇怪的部分是我可以调试它,获取它使用的实际查询字符串,将它放入 MySQL 并使用 @search_term 参数集运行它,并在它暂停时获得结果。让代码继续,我得到 0 个结果。字面上唯一不同的是,一个是预编译的字符串,另一个使用String.Format。

'@' 和 '%' 是否被 String.Format 视为特殊字符,还是我在这里没有看到的其他内容?格式化的字符串实际上是逐字节地等于两个非格式化字符串之一,同样,将其粘贴到 MySQL 实际上会从格式化字符串中得到结果。 Dapper 似乎只喜欢两个,而不是第三个,即使它完全等于前两个之一。

【问题讨论】:

    标签: c# sql string-formatting dapper


    【解决方案1】:

    请准确地说明您的query 和term 在失败的示例中是什么。我无法在这里重现任何问题。如果我使用发布的代码,query 与end_wildcard 相同,并且:它工作正常。在本地测试台(带有一些发明的数据)中,我有:

    connection.Query(end_wildcard, new { search_term = term }).Count().IsEqualTo(2);
    connection.Query(both_wildcards, new { search_term = term }).Count().IsEqualTo(3);
    connection.Query(query, new { search_term = term }).Count().IsEqualTo(2);
    

    如果你看到不同的东西,我只能得出结论,它一定与你的具体例子有关。

    但要具体一点:

    '@' 和 '%' 是否被 String.Format 视为特殊字符,还是我在这里看不到的其他字符?

    不; string.Format 只关心 {n}(整数 n)和 {{ / }}(分别是 { 和 } 的转义序列)之类的东西。

    基本上,我发现 dapper 不太可能做任何与此相关的事情,但显示您的确切 query 和 term,它们在失败时出现会有所帮助。

    【讨论】:

    • 嗯,这很奇怪。你是绝对正确的。它没有任何问题。计算机在一夜之间重新启动,今天早上,一切正常。我认为这只是 VS 以某种方式损坏的问题之一。每隔几天,我的 Web API 项目就会发现它缺少对 SQLite 的引用,尽管在我的项目中根本找不到它。顺便说一句,感谢 Dapper。太棒了。
    • @Chris 今天早些时候发布了一个新版本 BTW
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2017-09-10
    • 1970-01-01
    • 1970-01-01
    • 2021-09-24
    • 2016-04-25
    • 2011-02-02
    相关资源
    最近更新 更多