Es ist nichts falsch mit der generierten Abfrage, es ist genau so, wie es sein sollte. Ihre Abfrage fragt nach Namen, die mit der exakten Zeichenfolge [0-9]
beginnen.
String.StartsWith(x)
ist eine Zeichenfolge Methode, die überprüft, ob eine Zeichenfolge mit einem Literal ohne Mustervergleich beginnt. Linq to Entities übersetzt dies LIKE 'x%'
wobei x
eine literale Zeichenfolge, kein Muster ist. [
ist jedoch ein Sonderzeichen in einer LIKE-Anweisung. Dies bedeutet, dass es mit LIKE '~[0-9]%' escape '~'
maskiert werden muss. Mit dem Operator LIKE
können Sie das Escape-Zeichen angeben, in diesem Fall ~
.
Ich vermute, dass Sie keine Namen wollten, die mit [0-9]
beginnen, aber diejenigen, die mit einer Ziffer beginnen, also LIKE '[0-9]%'
. String.StartsWith unterstützt keine Muster und es gibt auch keine andere String
-Methode.
Eine Lösung besteht darin, in Ihrer Abfrage SqlFunctions.PatIndex zu verwenden und nach Zeilen zu filtern, die 1 zurückgeben. Ich würde jedoch den Ausführungsplan überprüfen, weil ich vermute, dass die Abfrage langsamer sein wird. LIKE '[0-9]%
ist im Wesentlichen eine Bereichssuche für alle Zeichenfolgen, die von 0
bis zu dem Buchstaben nach 9
mit Ausnahme von A
beginnen. Dies bedeutet, dass der Server Indizes unter Name
verwenden kann. Bei PATINDEX müssen möglicherweise alle Zeilen verarbeitet werden.
Leider SqlFunctions
enthält nicht Like
oder eine ähnliche Methode, die eine LIKE
-Anweisung mit Mustervergleich generieren würde.
Eine andere Möglichkeit besteht darin, tatsächlich eine Bereichsabfrage mit a.Name >="0" && a.Name <"A"
anzufordern.
UPDATE - NATURAL SORTIER-
Dies ist ein Fall des XY Problem. Das eigentliche Problem X ist, wie eine natürliche Sortierung mit LINQ zu Entitäten durchgeführt wird. Einer der T-SQL-Lösungen für natürliche Sortierung ist eine Formel, in der ORDER BY-Klausel in Verbindung mit dem Namen, selbst zu verwenden Zahlen nach Klartext erscheinen zu lassen, zum Beispiel:
ORDER BY case when name like '[0-9]%' then 1 else 0 end, name
Leider ist diese doesn Ich arbeite nicht mit EF, weil es kein LIKE
mit Mustern gibt.
Die gleiche Anordnung kann mit PATINDEX durchgeführt werden, die Funktion zur Verfügung durch die SqlFunctions.PatIndex ist:
order by name, case when PATINDEX('[0-9]%',name)=1 then 1 else 0 end
Der entsprechende Code LINQ könnte sein:
query.OrderBy(a => {
SqlFunctions.PatIndex("[0-9]%",a.Name)==1? 1:0,
a.Name
})
Sie dies nicht tun, weil da ist nichts falsch. '[' 'ist ein Sonderzeichen, das es zu verlassen gilt, und genau das macht EF. Die Abfrage ist korrekt wie sie ist. Sie haben nach Namen gefragt, die mit der exakten Zeichenfolge '[0-9]' beginnen. Wenn Sie keine Ergebnisse erhalten, liegt das daran, dass es keine Zeile gibt, die mit dem exakten String '[0-9]' –
beginnt. Ich erhalte das Ergebnis in sql server nach dem Entfernen der angehängten Tilde (~). Es ist nicht entkommen. – Aby
Ihre Abfrage fragt nach Namen, die mit '[0-9]' ** GENAU ** beginnen. Sie fragen nach '[0-9] George' und' [0-9] Pete', nicht nach '0George'. Durch das Entfernen des Escape-Zeichens führen Sie eine komplett andere Abfrage aus. Sie können den Mustervergleich nicht mit 'StartsWith' verwenden. Hast du versucht, Namen zu finden, die mit einer Nummer beginnen? –