我对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似乎只喜欢两个,而不是第三个,即使它与前两个中的一个完全相同。
答案 0 :(得分: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
)和{{
/ }}
({
和{}
的转义序列。分别为{1}}。
基本上,我发现dapper不太可能正在做与此相关的任何事情,但显示确切的query
和term
,,因为它们在失败时出现会有所帮助