How can I sort a list based on a user's selections in ASP.NET MVC?
Asked Answered
R

2

5

I have a list of customers that can be sorted by anywhere from 1 to 6 fields based on a user's selection. The sort fields can be in any order. If I know the fields and the sequence ahead of time, sorting is easy:

customers = customers
                .OrderBy(c => c.LastName)
                .ThenBy(c => c.City)
                .ThenBy(c => c.Age).ToList();

How would I pass in the sort fields at runtime? Is there a way to do something like this?

    string sortField1 = "State";
    string sortField2 = "City";
    string sortField3 = "Type";

    customers = customers
                .OrderBy(c => c.sortField1)
                .ThenBy(c => c.sortField2)
                .ThenBy(c => c.sortField3).ToList();
Rademacher answered 11/1, 2012 at 22:33 Comment(0)
R
1

I solved this by chaining .OrderBy statements in a ForEach loop. An .OrderBy gets appended to my Linq query for each sort criterion selected by the user. By wrapping my list in an IQueryable, I'm able to see the Linq query as it is built.

IQueryable<CustomerMaster> query = customers.AsQueryable();

            // reverse the sort order (sorts are applied incrementally) 
            // We need the user's last
            // sort criteria to get applied first
            sortOrder.Reverse();

            foreach (var sortItem in sortOrder)
            {
                switch (sortItem)
                {
                    case "LName":
                        query = query.OrderBy(c => c.LName);
                        break;

                    case "State":
                        query = query.OrderBy(c => c.State);
                        break;

                    default:
                        query = query
                            .OrderBy(c => c.LName)
                            .ThenBy(c => c.State);
                        break;
                }
            }
            customers = query.ToList();
            // set the sortorder back to user's order
            sortOrder.Reverse();
        }

Resulting query:

query = {System.Collections.Generic
        .List`1[CustomerMaster]
        .OrderBy(c => c.LName)
        .OrderBy(c => c.State)}
Rademacher answered 12/1, 2012 at 19:48 Comment(0)
S
1

Have a look at http://tomasp.net/articles/dynamic-linq-queries.aspx for a tutorial on how to build Dynamic LinQ queries at runtime. This should be what you are looking for.

Schreibe answered 11/1, 2012 at 22:44 Comment(1)
I read through Tomas' post. I also looked at Scott Guthrie's post (from 2008) on dynamic linq. I didn't like that both of those trails seem dead. Tomas has a link to a CodePlex project of his that was in alpha in 2007 and hasn't been touched since. Fortunately the solution of chaining a variable number of .OrderBy's works for me.Rademacher
R
1

I solved this by chaining .OrderBy statements in a ForEach loop. An .OrderBy gets appended to my Linq query for each sort criterion selected by the user. By wrapping my list in an IQueryable, I'm able to see the Linq query as it is built.

IQueryable<CustomerMaster> query = customers.AsQueryable();

            // reverse the sort order (sorts are applied incrementally) 
            // We need the user's last
            // sort criteria to get applied first
            sortOrder.Reverse();

            foreach (var sortItem in sortOrder)
            {
                switch (sortItem)
                {
                    case "LName":
                        query = query.OrderBy(c => c.LName);
                        break;

                    case "State":
                        query = query.OrderBy(c => c.State);
                        break;

                    default:
                        query = query
                            .OrderBy(c => c.LName)
                            .ThenBy(c => c.State);
                        break;
                }
            }
            customers = query.ToList();
            // set the sortorder back to user's order
            sortOrder.Reverse();
        }

Resulting query:

query = {System.Collections.Generic
        .List`1[CustomerMaster]
        .OrderBy(c => c.LName)
        .OrderBy(c => c.State)}
Rademacher answered 12/1, 2012 at 19:48 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.