我正在构建一个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
列表中高于1的每个项动态生成一个新的Order
吗?
答案 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]);
}
}
}