无法编写Extension方法来包装NEST客户端方法

问题描述 投票:0回答:1

基本上,我试图编写以下扩展方法,以避免不断编写.Suffix("keyword")。我不喜欢在整个地方都有字符串文字,我的ElasticSearch索引的多个属性恰好需要添加关键字后缀才能正确查询。

public static class NestHelperExtensions
{
    public static object UseKeywordSuffix(this object @object)
    {
        return @object.Suffix("keyword");
    }
}

如果我使用上面提到的方法,它不会应用后缀,但我不确定为什么它不起作用。我可能会以错误的方式进行此操作,也许有一种方法可以添加模型属性或某些东西来构建nestCilent.Search<T>,但是当我尝试使用KeywordAttribute时,这似乎也没有用。

任何人都可以提供一个解释,为什么它不会这么简单,如果它应该可能,你能提供一个例子或解决方法,例如使用属性?

elasticsearch .net-core nest
1个回答
1
投票

这不会起作用,因为Suffix method is specifically handled when visiting the field expression

if (methodCall.Method.Name == nameof(SuffixExtensions.Suffix) && methodCall.Arguments.Any())
{
    VisitConstantOrVariable(methodCall, _stack);
    var callingMember = new ReadOnlyCollection<Expression>(
        new List<Expression> { { methodCall.Arguments.First() } }
    );
    Visit(callingMember);
    return methodCall;
}

所以,像上面这样的扩展方法需要被称为Suffix才能开始,它必须至少有一个参数。您可能会想到提供一个默认值为“keyword”的可选参数会起作用,但表达式树不支持此功能,因此不起作用。

另一种方法是在AppendSuffix上使用Expression<Func<T, object>>扩展方法来构建一些东西;使用它的最好方法是将lambda表达式从流畅的调用中拉出来并转换为变量

public static class NestHelperExtensions
{
    public static Expression<Func<T, object>> KeywordSuffix<T>(this Expression<Func<T, object>> expression)
    {
        return expression.AppendSuffix("keyword");
    }
}

var client = new ElasticClient();

Expression<Func<Person, object>> firstName = f => f.FirstName;  

var searchResponse = client.Search<Person>(s => s
    .Query(q => q
        .Match(m => m
            .Field(firstName.KeywordSuffix())
            .Query("bar")
        )
    )
);

不太好的方法是将lambda表达式转换为Expression<Func<T, object>>内联

var searchResponse = client.Search<Person>(s => s
    .Query(q => q
        .Match(m => m
            .Field(((Expression<Func<Person, object>>)(f => f.FirstName)).KeywordSuffix())
            .Query("bar")
        )
    )
);

另一种可能更简单的方法是为字符串"keyword"引入一个常量,并在Suffix扩展方法中使用它;它避免在整个地方使用字符串文字。

© www.soinside.com 2019 - 2024. All rights reserved.