0

I have something like this:

        if (sort == "Customer")
        {
            if (sortDirection == SortDirection.Descending)
                myList = myList.OrderByDescending(e => e.SiteOrganization.Organization.Name).ToList();
            else
                myList = myList.OrderBy(e => e.SiteOrganization.Organization.Name).ToList();
        }
        if (sort == "RequestType")
        {
            if (sortDirection == SortDirection.Descending)
                myList = myList.OrderByDescending(e => e.TypeId).ToList();
            else
                myList = myList.OrderBy(e => e.TypeId).ToList();
        }
        if (sort == "RequestedByShort")
        {
            if (sortDirection == SortDirection.Descending)
                myList = myList.OrderByDescending(e => e.RequestedByUser.ShortName).ToList();
            else
                myList = myList.OrderBy(e => e.RequestedByUser.ShortName).ToList();
        }

I would like to clean this up to have something like

if (sortDirection == SortDirection.Descending)
                myList = myList.OrderByDescending(e => e.RequestedByUser.ShortName).ToList();
            else
                myList = myList.OrderBy(e => e.RequestedByUser.ShortName).ToList();

So that I only have ONE LINQ query no matter what "sort" it is. Any suggestions?

Omid
  • 793
  • 1
  • 9
  • 30

1 Answers1

4

If you move your sort logic into a method, you can pass the predicate straight in e.g.

public IList<TSource> SortBy<TSource, TMember>(IEnumerable<TSource> list, Func<TSource, TMember> selector, SortDirection direction)
{
    if (direction == SortDirection.Descending)
        return list.OrderByDescending(selector).ToList();
    else
        return list.OrderBy(selector).ToList();
}
...
if (sort == "Customer") {
    list = SortBy(list, x => x.SiteOrganization.Organization.Name, SortDirection.Descending);
} else if (sort == "RequestType") {
    list = SortBy(list, x => x.TypeId, SortDirection.Ascending);
} else if (sort == "RequestedByShort") {
    list = SortBy(list, x => x.RequestedByUser.ShortName, SortDirection.Descending);
}

Live demo


If you wanted to use this as a general solution to all lists, you could create it as an extension method

public static class ListExt
{
    public static IList<TSource> SortBy<TSource, TMember>(this IEnumerable<TSource> list, Func<TSource, TMember> selector, SortDirection direction)
    {
        if (direction == SortDirection.Descending) {
            return list.OrderByDescending(selector).ToList();
        } else {
            return list.OrderBy(selector).ToList();
        }
    }
}
...
list = list.SortBy(x => x.TypeId, SortDirection.Ascending);
James
  • 75,060
  • 17
  • 154
  • 220
  • Although I like the `SortBy` method, you've kinda glossed over the original `sort` variable. – Rawling Aug 28 '14 at 14:46
  • @Rawling I guess the point of the answer was to target the crux of the problem. I can update to accommodate the `sort` parameter as well. – James Aug 28 '14 at 14:48
  • Not me, but I've just noticed you're only passing one generic argument to a two-generic-argument method. – Rawling Aug 28 '14 at 15:08
  • 1
    +1 for `general solution to all lists`. I was going to post one myself after reading your first half of the answer. – Neolisk Aug 28 '14 at 15:09
  • @Rawling the second generic argument is implied by the predicate so it's not required. In fact, it's all implied therefore I shouldn't need to pass any arguments the more I think about it. Neolisk yeah upon writing the answer I realised that it is generic enough to be re-used, I also think the `SortDirection` enum could be simplified to an `asc` bool (unless the OP has other sorting conditions). – James Aug 28 '14 at 15:13