Entity framework core 正在尝试在EFCore扳手提供程序上添加对索引使用的支持

Entity framework core 正在尝试在EFCore扳手提供程序上添加对索引使用的支持,entity-framework-core,google-cloud-spanner,Entity Framework Core,Google Cloud Spanner,我正在为EF Core for Spaner编写一个驱动程序——在基本层面上,它可以工作,我可以编写读写查询,将其转换为Spaner SQL,执行并返回结果等 现在,我尝试添加对具有二级索引的读取查询的支持 Ultimately I'm trying to generate this SQL Query: SELECT * FROM PostTags@{ FORCE_INDEX = PostTagsByTagId } WHERE TagId = 1 From This Linq: var p

我正在为EF Core for Spaner编写一个驱动程序——在基本层面上,它可以工作,我可以编写读写查询,将其转换为Spaner SQL,执行并返回结果等

现在,我尝试添加对具有二级索引的读取查询的支持

Ultimately I'm trying to generate this SQL Query: 
SELECT * FROM PostTags@{ FORCE_INDEX = PostTagsByTagId } WHERE TagId = 1

From This Linq:
var postTag = ctx.PostTags.WithIndex("PostTagsByTagId").Where(x => x.TagId == 1).FirstOrDefault();
我添加了如下扩展方法:

public static class SpannerIndexSupport
{
    public static IQueryable<TSource> WithIndex<TSource>(this IQueryable<TSource> query, string indexName)
    {
        var methodDefinition = typeof(SpannerIndexSupport).GetTypeInfo().GetMethods().Single(m => m.Name == "WithIndex");
        var method = methodDefinition.MakeGenericMethod(typeof(TSource));
        var args = new[] { query.Expression, Expression.Constant(indexName) };
        var expression = Expression.Call(null, method, args);
        return query.Provider.CreateQuery<TSource>(expression);
    }
}
公共静态类span索引支持
{
带索引的公共静态IQueryable(此IQueryable查询,字符串indexName)
{
var methodDefinition=typeof(spanrindexsupport).GetTypeInfo().GetMethods().Single(m=>m.Name==“WithIndex”);
var method=methodDefinition.MakeGenericMethod(typeof(TSource));
var args=new[]{query.Expression,Expression.Constant(indexName)};
var expression=expression.Call(null,method,args);
返回query.Provider.CreateQuery(表达式);
}
}
并试图编写IAsyncQueryProvider来支持它,但找不到使其工作的方法。
任何人有什么想法吗?

在官方的扳手EFCore库()中,我将首先在扳手QuerySqlGenerator中重写VisitTable(TableExpression TableExpression):

这将允许您进行概念验证,因为您可以直接影响那里生成的SQL文本。 一旦成功了,你就要把它做好

我想可能有几种方法可以让这一切顺利进行。最简单的方法可能是在Linq表达式树中有一些自定义的no op方法标记,然后注册一个IMethodCallTranslator,将其转换为自定义的特定于扳手的表达式(其接受调用到SqlGenerator以生成正确的Sql)或者可能创建一个SqlTranslatingExpressionVisitor,将表表达式切换到允许FORCE_索引的自定义表达式


很抱歉,我无法提供更多帮助。

嘿,非常感谢您的反馈,实际上我的计划是修改Visitable方法。我遇到的问题是如何向visitTable方法发送信号,该方法以及何时执行修改。这实际上是你回答的第二部分,我还不知道如何克服它。我尝试了你建议的一些解决方案和其他一些,但目前无法奏效。。我目前正在研究它并深入研究EF代码。一旦我有了工作,我就会更新:)快速更新-我已经用一个肮脏的黑客使它工作了-但至少现在它可以工作:)-我使用了“PanerRuseIndexTranslator:IMethodCallTranslator”和一个参数,即“var results=(来自ctx.PostTags中的p,其中p.TagId==1&&p.TagId.UseIndex(“PostTags”,“AAA”)选择p.FirstOrDefault();' 它将很快变为x=>x.SomeThing,并带有属性,而不是向UseIndex提供字符串。非常有限&刚刚被黑客入侵:)听起来你进步很大!我更喜欢您的第一个表单,但我想您无法在methodcalltranslator或membertranslator中捕获WithIndex()?如果我记得的话,还有一个访问者模式,可以访问整个表达式树并对其进行转换。我不相信扳手efcore提供商已经注册了一个。顺便说一句,如果您愿意的话,一旦您完成了,我们将感谢您的任何PRs。我明白了。这绝对不容易。将类型返回为bool并不十分理想。有没有可能定义自己的表达方式,类似于我喜欢在postgres中的表达方式(请参阅)。当您返回自己的自定义表达式时,可以严格控制生成的SQL,并且只需在列上不发出额外的调用。也许该表达式的sqlgenerator可以存储一些状态,以便在正确的位置显示索引使用情况?谢谢!我将分析你的建议,并更新调查结果。