String.Format mit SQL-Platzhalter verursacht Dapper-Abfrage, um zu brechen

c# dapper sql string-formatting

Frage

Ich habe ein seltsames Problem mit Dapper und String Formatierung. Hier ist der relevante Code:

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

Die ersten beiden Abfragen, bei denen die CONCAT-Anweisungen mit Platzhaltern in die Zeichenfolge eingebettet sind, funktionieren einwandfrei. Wenn ich jedoch die CONCAT-Anweisungen herausbringe und das eine oder andere mit String.Format injiziere, bekomme ich 0 Ergebnisse.

Der merkwürdigste Teil davon ist, dass ich es debuggen kann, den tatsächlichen Abfrage-String, den er verwendet, in MySQL einfüge und ihn mit einem @search_term-Parametersatz laufe und Ergebnisse erhalte, während er angehalten wird. Lassen Sie den Code fortfahren, und ich bekomme 0 Ergebnisse. Wörtlich ist das einzige, was anders ist, dass eine eine vorkompilierte Zeichenfolge ist und die andere String.Format verwendet.

Werden '@' und '%' von String.Format als Sonderzeichen betrachtet oder gibt es etwas anderes, das ich hier nicht sehe? Die formatierte Zeichenkette ist wörtlich Byte für Byte gleich einer der beiden nicht formatierten Zeichenketten und wieder fügt das Einfügen in MySQL tatsächlich Ergebnisse aus der formatierten Zeichenkette ein. Dapper scheint nur zwei zu mögen, und nicht der dritte, auch wenn es genau gleich einem der ersten beiden ist.

Akzeptierte Antwort

Bitte geben Sie in dem Beispiel, das fehlschlägt, genau an, was Ihre query und Ihr term sind. Ich kann hier kein Problem reproduzieren. Wenn ich den Code wie gepostet end_wildcard , ist die query identisch mit end_wildcard und: es funktioniert end_wildcard . In einem lokalen Prüfstand (mit einigen erfundenen Daten) habe ich:

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);

Wenn Sie etwas anderes sehen, kann ich nur schlussfolgern, dass es sich auf Ihr konkretes Beispiel beziehen muss.

Aber um genau zu sein:

Werden '@' und '%' von String.Format als Sonderzeichen betrachtet oder gibt es etwas anderes, das ich hier nicht sehe?

Nee; string.Format kümmert sich nur um Dinge wie {n} (für Integer n ) und {{ / }} (die Escape-Sequenzen für { bzw. } sind).

Grundsätzlich finde ich es unwahrscheinlich, dass Dapper etwas damit zu tun hat, aber es würde helfen , wenn man genau die query und den term , wie sie aussehen, wenn sie scheitern .



Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum
Lizenziert unter: CC-BY-SA with attribution
Nicht verbunden mit Stack Overflow
Ist diese KB legal? Ja, lerne warum