【发布时间】: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