【问题标题】:Unable to write Extension method to wrap a NEST client method无法编写扩展方法来包装 NEST 客户端方法
【发布时间】:2019-07-16 22:09:37
【问题描述】:

基本上,我试图编写以下扩展方法以避免必须不断编写.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】:

    这不起作用,因为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”的可选参数会起作用,但表达式树不支持这一点,因此不会起作用。

    另一种方法是在Expression&lt;Func&lt;T, object&gt;&gt; 上使用AppendSuffix 扩展方法来构建一些东西;最好的使用方法是将 lambda 表达式从 fluent 调用中提取出来并放入一个变量中

    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&lt;Func&lt;T, object&gt;&gt; inline

    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 扩展方法中使用它;它避免了到处使用字符串文字。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2015-09-01
      • 2018-02-23
      • 2019-05-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多