Невозможно записать метод Extension для переноса метода клиента NEST - PullRequest
0 голосов
/ 22 февраля 2019

По сути, я пытался написать следующий метод расширения, чтобы избежать необходимости постоянно писать .Suffix("keyword").Мне не нравится иметь строковые литералы повсюду, и для нескольких свойств моих индексов ElasticSearch требуется добавить суффикс ключевого слова для правильного запроса.

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

Если я использую метод, представленный выше, он не применяетсясуффикс, но я не уверен, почему это не сработает.Возможно, я ошибаюсь в этом, и, возможно, есть способ добавить атрибут модели или что-то для построения nestCilent.Search<T>, но когда я попытался использовать KeywordAttribute, это тоже не сработало.

Может ли кто-нибудь предложить объяснение, почему это не будет так просто, и если это возможно, можете ли вы привести пример или обходной путь, например, используя атрибуты?

1 Ответ

0 голосов
/ 23 февраля 2019

Это не будет работать, потому что метод Suffix специально обрабатывается при посещении выражения поля

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, чтобы начать, и у него должен быть хотя бы один аргумент.Вы могли бы подумать о предоставлении необязательного параметра со значением по умолчанию «ключевое слово», который будет работать, но деревья выражений не поддерживают это, поэтому не будут работать.

Другой подход заключается в использовании расширения AppendSuffixметод Expression<Func<T, object>> чтобы что-то построить;самый хороший способ использовать это - извлечь лямбда-выражение из свободного вызова в переменную

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")
        )
    )
);

Не очень приятный способ 1016 * будет приводить лямбда-выражение к Expression<Func<T, object>> 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;он избегает использования строкового литерала повсюду.

...