我需要 SQLiteglob
(C#) 方法中必须返回的函数Expression<Func<RandomEntity, bool>>
——我需要glob
因为只有这样才使用索引(已经使用检查过EXPLAIN QUERY PLAN [..]
).
所以我添加了以下函数映射到<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>
和一个 C# 存根方法:
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>>!");
}
}
以及用法(只是一个生成微小 SQL 的示例):
var count = context.Users.Count(u => SQLiteFunctions.Glob("admin*", u.Name));
虽然这有效,但生成的 SQL 使用了“愚蠢的”= 1
比较,因为模型只知道数据类型“位”(即 0 或 1),并且我发现没有真正的布尔类型,尽管本机 glob 函数似乎是真正的布尔类型:
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]
问题:这样(使用“= 1”)SQLite不使用索引,查询速度非常慢。如果我删除 3 个字符“= 1”,查询会变得更快,并且查询计划也会从“SCAN TABLE”更改为“SEARCH TABLE USING INDEX”。
有什么想法如何使该函数成为真正的布尔函数吗?
添加:
我还尝试使用 CSDL 部分 ():
<Function Name="GlobMatch" ReturnType="Edm.Boolean">
<Parameter Name="globPattern" Type="Edm.String" />
<Parameter Name="target" Type="Edm.String" />
<DefiningExpression> glob(globPattern, target) </DefiningExpression>
</Function>
and
[DbFunction("DoPiMo", "GlobMatch")]
public static bool Glob2(string globPattern, string target)
{
throw new NotImplementedException("Only exists for IQueryable/Expression<Func<T,bool>>!");
}
但这只会产生一个运行时错误,指出“glob”未定义/已知。