Как сгенерировать динамическое количество предложений ThenBy в Спецификации - PullRequest
0 голосов
/ 10 января 2019

Я создаю Spec Evaluator, который должен учитывать несколько возможных OrderBy, как в следующем примере:

if (spec.Order != null)
{
    var count = spec.Order.Count;

    if (count == 1)
    {
        query = query.OrderBy(spec.Order[0]);
    }
    else if (count == 2)
    {
        query = query.OrderBy(spec.Order[0])
            .ThenBy(spec.Order[1]);
    }
    else if (count == 3)
    {
        query = query.OrderBy(spec.Order[0])
            .ThenBy(spec.Order[1])
            .ThenBy(spec.Order[2]);
    }
    // And so on...
}

Query - это IQueryable, spec.Order - это список предложений: List<Expression<Func<T, object>>>.

Я знаю, что могу использовать OrderBy со всеми предложениями, передаваемыми в виде строки. И я думаю, я могу просто спроецировать все предложения Order на новую строку через запятую. Но это решение не кажется чистым.

Есть ли другой способ динамически генерировать один новый ThenBy для каждого элемента списка Order, выше 1?

1 Ответ

0 голосов
/ 10 января 2019

Вы можете использовать цикл for. По сути, переберите все значения Order, используйте OrderBy для первого и ThenBy для последующих элементов. Поскольку вы сказали, что используете IQueryable, я изменил это, чтобы использовать временную переменную IOrderedQueryable<T>.

if (spec.Order != null)
{
    var count = spec.Order.Count;

    IOrderedQueryable<T> orderedQuery = null;
    for (int i = 0; i < count; ++i)
    {
        if (i == 0)
        {
            orderedQuery = query.OrderBy(spec.Order[i]);
        }
        else
        {
            orderedQuery = orderedQuery.ThenBy(spec.Order[i]);
        }
    }
    query = orderedQuery ?? query;
}

Вы также можете подойти к этому следующим образом, хотя я не уверен, как производительность отличается между двумя методами, если она вообще существует:

if (spec.Order != null)
{
    var count = spec.Order.Count;

    for (int i = 0; i < count; ++i)
    {
        if (query is IOrderedQueryable<T> orderedQuery)
        {
            query = orderedQuery.ThenBy(spec.Order[i]);
        }
        else
        {
            query = query.OrderBy(spec.Order[i]);
        }
    }
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...