如何在规范中生成动态数量的ThenBy子句

时间:2019-01-10 04:04:46

标签: c# linq

我正在构建一个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...
}

QueryIQueryablespec.Order是子句列表:List<Expression<Func<T, object>>>

我知道我可以将OrderBy与所有作为字符串传递的子句一起使用。而且我想我可以将所有Order子句投影到一个用逗号分隔的新字符串中。但是该解决方案似乎并不干净。

还有其他方法可以为ThenBy列表中高于1的每个项动态生成一个新的Order吗?

1 个答案:

答案 0 :(得分:4)

您可以使用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]);
        }
    }
}