# Big switch statement for sorting a table

I have a webpage with a table. The table, with 10 columns, can be sorted by each column ascending or descending.

At this moment I control order by big switch:

Func<IQueryable<DeviceUsage>, IOrderedQueryable<DeviceUsage>> orderBy;
IOrderedEnumerable<DeviceUsage> info;
switch (sortOrder)
{
case "user":
ViewBag.sortableBy = sortOrder;
info = unitOfWork.deviceUsageRepository.Get(where, null, null, d => d.DeviceInstance, d => d.Storage, d => d.User).OrderBy(s => s.User.FullName);
ViewBag.Desc = true;
return PartialView(info.ToPagedList(pageNumber, 15));
case "userDesc":
ViewBag.sortableBy = sortOrder;
info = unitOfWork.deviceUsageRepository.Get(where, null, null, d => d.DeviceInstance, d => d.Storage, d => d.User).OrderByDescending(s => s.User.FullName);
ViewBag.Desc = true;
return PartialView(info.ToPagedList(pageNumber, 15));
case "manufacturer":
ViewBag.sortableBy = sortOrder;
orderBy = q => q.OrderBy(o => o.DeviceInstance.Device.Manufacturer1.Name);
break;
case "manufacturerDesc":
ViewBag.sortableBy = sortOrder;
orderBy = q => q.OrderByDescending(o => o.DeviceInstance.Device.Manufacturer1.Name);
break;
.
.
.
default:
ViewBag.sortableBy="";
orderBy=q => q.OrderBy(o => o.DeviceInstance.Device.CatalogNo);
break;
}


This code works but looks not nice. I think it's the longest switch I ever wrote. Can it be someway upgraded or leave it as it is?

Explanation why there is difference in logic:

As you can see in user I'm sorting by Fullname which isn't in db ( its created locally in DAL from FirstName & LastName). @Nick's approach is ok BUT adding a new Desc variable is a bit problematic because there is only the possibility to sort by ONE row at a time. So I would need to store it somewhere in the last sorting order.

• I agree with Nick, there seems to be logic that doesn't match eachother going on here. That leads me to believe there may be an entirely different approach. Can you give us some more context to this? Also, have you tried using a DataTable and letting it handle the sorting for you? – Steve Michael Oct 2 '14 at 11:47
• Updated my question with some more context – szpic Oct 2 '14 at 12:27
• I am not sure I am fully understanding but could you just create a ViewModel that has all of the information you need. This can include the matching of First and Last name. Then once you have that you can simply pass that to your view and use a DataTable to deal with the sorting? – Steve Michael Oct 2 '14 at 13:43
• Yes I can create viewModel but I'was trying to avoid this because if I add viewmodel here I'll need to add it at all other views which will end in rewriting nearly half of an app :) – szpic Oct 2 '14 at 18:45
• Not necessarily! I think it would be more preferably than having this type of code. It's very convoluted. Just my two cents :) Try it that way and if you don't like it then trash it! – Steve Michael Oct 2 '14 at 20:42

As a quick improvement you should move the line ViewBag.sortableBy... out of your case statement and only set it in the default.

Secondly, I'm noticing there seem to be two different kinds of logic going on here: whether somebody's a user or a manager, etc. or whether the order is ascending or descending. It may be a lot easier to do something like this:

    Func<IQueryable<DeviceUsage>, IOrderedQueryable<DeviceUsage>> orderBy;
IOrderedEnumerable<DeviceUsage> info;
ViewBag.sortableBy = ascending? sortField : sortField + "desc";

switch (sortField)
{
case "user":

var deviceUsage = unitOfWork.deviceUsageRepository.Get(where, null, null, d => d.DeviceInstance, d => d.Storage, d => d.User);
var orderFunction = s => s.User.FullName;
ViewBag.Desc = true;
info = ascending? deviceUsage.OrderBy(orderFunction); : deviceUsage.OrderByDescending(orderFunction);
return PartialView(info.ToPagedList(pageNumber, 15));
case "manufacturer":
var orderFunction = o => o.DeviceInstance.Device.Manufacturer1.Name;
orderBy = ascending? q => q.OrderBy(orderFunction) : q => q.OrderByDescending(orderFunction)
break;
.
.
.
default:
ViewBag.sortableBy="";
orderBy=q => q.OrderBy(o => o.DeviceInstance.Device.CatalogNo);
break;
}


This code obviously requires you to split out whether an order is ascending or not beforehand. This can be done with string manipulation if necessary, but there is probably an easier way using code you haven't shown us.