无法编写扩展方法来包装 NEST 客户端方法
Unable to write Extension method to wrap a NEST client method
基本上,我试图编写以下扩展方法以避免必须不断地编写 .Suffix("keyword")
。我不喜欢到处都是字符串文字,而且我的 ElasticSearch 索引的多个属性恰好需要添加关键字后缀才能正确查询。
public static class NestHelperExtensions
{
public static object UseKeywordSuffix(this object @object)
{
return @object.Suffix("keyword");
}
}
如果我使用上面介绍的方法,它不会应用后缀,但我不确定为什么它不起作用。我可能以错误的方式解决这个问题,也许有一种方法可以添加模型属性或其他东西来构建 nestCilent.Search<T>
,但是当我尝试使用 KeywordAttribute
时,似乎没有要么工作。
任何人都可以解释为什么它不会这么简单吗?如果可能的话,你能提供一个例子或解决方法吗?使用属性?
这行不通,因为 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<Func<T, object>>
上利用 AppendSuffix
扩展方法来构建一些东西;使用它的最好方法是将 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
扩展方法中使用它;它避免在所有地方使用字符串文字。
基本上,我试图编写以下扩展方法以避免必须不断地编写 .Suffix("keyword")
。我不喜欢到处都是字符串文字,而且我的 ElasticSearch 索引的多个属性恰好需要添加关键字后缀才能正确查询。
public static class NestHelperExtensions
{
public static object UseKeywordSuffix(this object @object)
{
return @object.Suffix("keyword");
}
}
如果我使用上面介绍的方法,它不会应用后缀,但我不确定为什么它不起作用。我可能以错误的方式解决这个问题,也许有一种方法可以添加模型属性或其他东西来构建 nestCilent.Search<T>
,但是当我尝试使用 KeywordAttribute
时,似乎没有要么工作。
任何人都可以解释为什么它不会这么简单吗?如果可能的话,你能提供一个例子或解决方法吗?使用属性?
这行不通,因为 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<Func<T, object>>
上利用 AppendSuffix
扩展方法来构建一些东西;使用它的最好方法是将 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
扩展方法中使用它;它避免在所有地方使用字符串文字。