views:

145

answers:

1

Hi there,

Trying something with Linq / Lambda's, but have no idea where to search.

I'm working on some simple sorting in an ASP.net GridView. Here's some sample code:

IQueryable<User> query = (from c in users select c).AsQueryable<User>();

if (isAscending)
{
    switch (e.SortExpression)
    {
        case "Name":
            query.OrderBy(c => c.Name);
            break;
        default:
            break;
    }
}
else
{
    switch (e.SortExpression)
    {
        case "Name":
            query.OrderByDescending(c => c.Name);
            break;
         default:
             break;
    }
}

grid.DataSource = query.ToList();
grid.DataBind();

I am, however, unsatisfied with the code as it is very sensitive to errors and requires lots of duplicated code. I'm hoping to solve this using Lambda expressions instead, but I have no idea how. Here's what I would like to go to:

IQueryable<User> query = (from c in users select c).AsQueryable<User>();

var param = null;

switch (e.SortExpression)
{
    case "Name":
        param = (c => c.Name);
        break;
    default:
        break;
}

if (isAscending)
{
    query.OrderBy(param);
}
else
{
    query.OrderByDescending(param);
}

grid.DataSource = query.ToList();
grid.DataBind();

Could anyone please help me? Thanks!

+5  A: 

Your code is broken at the moment - you're calling OrderBy/OrderByDescending but not using the result. You need

query = query.OrderBy(param);

etc.

As for conditionally ordering - the problem is that you can't declare the type of param because the type of the ordering key may well vary depending on the sort expression.

As a workaround, you can write your own extension method:

public static IOrderedQueryable<TSource> OrderByWithDirection<TSource, TKey>
    (this IQueryable<TSource> source,
     Expression<Func<TSource, TKey>> keySelector,
     bool ascending)
{
    return ascending ? source.OrderBy(keySelector) 
                     : source.OrderByDescending(keySelector);
}

Your code would then become:

IQueryable<User> query = (from c in users select c).AsQueryable<User>();

switch (e.SortExpression)
{
    case "Name":
        query = query.OrderByWithDirection(c => c.Name, isAscending);
        break;
    // etc
    default:
        break;
}

(Why are you calling AsQueryable, by the way?)

Jon Skeet
As always, a gret answer, thanks!
FailBoy
Thanks for the reply. The code above was made from chunks of real code so I might have made some mistakes. It was more for the picture anyway.As for your answer: thanks! This is indeed a very nice solution. I take it the way I wanted is not possible?
Tijs Hendriks