Verwenden der GLOB-Funktion in LINQ to Entities
Ich brauche SQLitesglob
Funktion in einer (C #) -Methode, die zurückgeben mussExpression<Func<RandomEntity, bool>>
-- und ich braucheglob
denn nur dann wird der Index verwendet (bereits geprüft mitEXPLAIN QUERY PLAN [..]
).
Also habe ich die folgende Funktionszuordnung hinzugefügt<edmx:StorageModels><Schema>
(SSDL):
<Function Name="glob" Aggregate="false" BuiltIn="true" NiladicFunction="false" IsComposable="true" ReturnType="bit">
<Parameter Name="pattern" Mode="In" Type="nvarchar"/>
<Parameter Name="target" Mode="In" Type="nvarchar"/>
</Function>
und eine C # -Stub-Methode:
public static class SQLiteFunctions
{
[DbFunction("Model.Store", "glob")]
public static bool Glob(string pattern, string target)
{
throw new NotImplementedException("Only exists for IQueryable/Expression<Func<T,bool>>!");
}
}
und die Verwendung (nur ein Beispiel, das winziges SQL erzeugt):
var count = context.Users.Count(u => SQLiteFunctions.Glob("admin*", u.Name));
Während dies funktioniert, verwendet die resultierende SQL eine "dumme"= 1
Vergleich, da das Modell nur den Datentyp "bit" (0 oder 1) kennt und ich keinen echten Booleschen Typ gefunden habe, obwohl die native Glob-Funktion wahr zu sein scheint:
SELECT
[GroupBy1].[A1] AS [C1]
FROM ( SELECT
Count([Filter1].[A1]) AS [A1]
FROM ( SELECT
1 AS [A1]
FROM [Users] AS [Extent1]
WHERE (glob('admin*', [Extent1].[Name])) = 1
) AS [Filter1]
) AS [GroupBy1]
Das Problem: Auf diese Weise (mit "= 1") verwendet SQLite den Index nicht und die Abfrage ist sehr langsam. Wenn ich die 3 Zeichen "= 1" entferne, wird die Abfrage schnell und auch der Abfrageplan wechselt von "SCAN TABLE" zu "SEARCH TABLE USING INDEX".
Irgendwelche Ideen, wie man die Funktion zu einer echten Booleschen Funktion macht?
Zusatz:
Ich habe auch versucht, den CSDL-Abschnitt () zu verwenden:
<Function Name="GlobMatch" ReturnType="Edm.Boolean">
<Parameter Name="globPattern" Type="Edm.String" />
<Parameter Name="target" Type="Edm.String" />
<DefiningExpression> glob(globPattern, target) </DefiningExpression>
</Function>
und
[DbFunction("DoPiMo", "GlobMatch")]
public static bool Glob2(string globPattern, string target)
{
throw new NotImplementedException("Only exists for IQueryable/Expression<Func<T,bool>>!");
}
Dies erzeugt jedoch nur einen Laufzeitfehler, der besagt, dass "glob" nicht definiert / bekannt ist.