Mit EntityFramework führt die Klausel .OrderBy(x => x.Title.StartsWith("foo"))
zu SQL WHERE (Title LIKE 'foo%' ESCAPE '~')
.
Wenn ich den Ausführungsplan für die vollständige Abfrage anschaue, sehe ich, dass ich einen anderen Plan (einen, der den nicht gruppierten Index der Spalte verwendet) bekomme, wenn ich ESCAPE '~'
entferne.
Warum versucht EF, einer Zeichenkette zu entkommen, die sie nicht benötigt, und wie kann ich sie stoppen?
Der überflüssige ESCAPE
kann sicherlich die Kardinalitätsschätzungen ändern und einen anderen Plan geben. Obwohl lustigerweise fand ich, dass es in diesem Test mehr Genauigkeit als weniger macht!
Ohne Escape
Mit Escape
Kurz vor der Aktualisierung auf eine neuere Version von EF oder dem Schreiben Ihrer eigenen benutzerdefinierten DbProviderManifest
-Implementierung Ich denke, Sie haben kein Glück bei Ihrem Versuch, ESCAPE
zu entfernen.
Das Übersetzen von String.StartsWith
, String.EndsWith
und String.Contains
zu LIKE
anstelle von CHARINDEX
war neu in EF 4.0
Betrachtet man die Definition von System.Data.Entity, Version=4.0.0.0
im Reflektor, scheint die relevante Funktion (in System.Data.SqlClient.SqlProviderManifest
)
Die Signatur für diese Methode lautet
%Vor%Es ist also nur fest codiert, immer escape zu verwenden und das Flag, das zurückgegeben wird, wird ignoriert.
Diese Version von EF fügt also nur% ESCAPE '~'
an alle LIKE
Abfragen an.
Dies scheint etwas zu sein, das in der neuesten Codebasis verbessert wurde.
Die Definition von SqlFunctionCallHandler.TranslateConstantParameterForLike ist
%Vor% SqlProviderManifest.EscapeLikeText ist derselbe Code wie bereits gezeigt. Beachten Sie, dass es nun false
als zweiten Parameter übergibt und das Ausgabeparameter-Flag verwendet, um nur den ESCAPE
bei Bedarf anzuhängen.
Tags und Links sql .net sql-server c# entity-framework