I have a base razor component, that loads data from a SQL database. To pass a sort order to this component, there are two "sort" Func<T,object> parameters and two bool to set asc/desc.
In my query this leads to the folloging code:
if (sort1 != null && sort2 != null)
{
if (GridBehavior.SortOrderDescending1)
{
if (GridBehavior.SortOrderDescending2)
{
query = query.OrderByDescending(sort1).ThenByDescending(sort2);
}
else
{
query = query.OrderByDescending(sort1).ThenBy(sort2);
}
}
else
{
if (GridBehavior.SortOrderDescending2)
{
query = query.OrderBy(sort1).ThenByDescending(sort2);
}
else
{
query = query.OrderBy(sort1).ThenBy(sort2);
}
}
}
else if (sort1 != null)
{
if (GridBehavior.SortOrderDescending1)
{
query = query.OrderByDescending(sort1);
}
else
{
query = query.OrderBy(sort1);
}
}
This looks very "ugly" to me at one hand, at the other I don't want to think how this looks if I have to extend this to a 3rd or even 4th order clause.
Can this be done more generic? I can't query with orderby() in sequence, because sorting will always be done on the whole set, so one overwrites the next.
Any hint will be greatly appreciated!
P.S.: The code will also not work, if only sort2 is specified!
You can put it into a list and then loop through the list.
If you are using a database with EF Core then you should have Expression
s not bare Func
lambdas.
List<(Expression<Func<T,object>> expression, bool descending)> sorts = [
(sort1, GridBehavior.SortOrderDescending1),
(sort2, GridBehavior.SortOrderDescending2)
];
var sortedQuery = query.OrderBy(t => 1);
foreach (var tuple in sorts)
{
if (tuple.expression != null)
{
if (tuple.descending)
sortedQuery = sortedQuery.ThenByDescending(tuple.expression);
else
sortedQuery = sortedQuery.ThenBy(tuple.expression);
}
}
The first .OrderBy(t => 1);
will be optimized away by the database.