尝试在EFCore Spanner Provider上添加索引使用支持

时间:2018-01-23 20:33:02

标签: entity-framework-core google-cloud-spanner

我为EF Core for Spanner编写驱动程序 - 在基础级别它可以工作,我可以编写读写查询,将其转换为Spanner 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);
    }
}

并尝试编写IAsyncQueryProvider来支持它,但无法找到使其工作的方法。 任何想法任何人?

1 个答案:

答案 0 :(得分:0)

在官方的Spanner EFCore库(https://github.com/GoogleCloudPlatform/google-cloud-dotnet/tree/master/apis/Google.Cloud.EntityFrameworkCore.Spanner/Google.Cloud.EntityFrameworkCore.Spanner)中,我将首先在SpannerQuerySqlGenerator中覆盖VisitTable(TableExpression tableExpression):

https://github.com/GoogleCloudPlatform/google-cloud-dotnet/tree/master/apis/Google.Cloud.EntityFrameworkCore.Spanner/Google.Cloud.EntityFrameworkCore.Spanner/Query/Sql/Internal/SpannerQuerySqlGenerator.cs

这将允许您获得概念证明,因为您可以直接影响生成的SQL文本。 一旦有效,那么你会想要做到这一点。

我想可能有几种方法可以完成这项工作。最简单的可能是在Linq表达式树中有一些自定义的无操作方法标记,然后注册一个IMethodCallTranslator将其转换为自定义的特定于Spanner的Expression(其Accept调用SqlGenerator以生成正确的Sql)或者可能创建一个SqlTranslatingExpressionVisitor将表表达式切换为允许FORCE_INDEX的自定义表达式。

对不起,我帮不了多忙。