Как отсортировать список на основе выбора пользователя в ASP.NET MVC?

У меня есть список клиентов, которые можно отсортировать по 1-6 полям в зависимости от выбора пользователя. Поля сортировки могут быть в любом порядке. Если я заранее знаю поля и последовательность, сортировка выполняется легко:

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

Как мне передать поля сортировки во время выполнения? Есть ли способ сделать что-то подобное?

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

    customers = customers
                .OrderBy(c => c.sortField1)
                .ThenBy(c => c.sortField2)
                .ThenBy(c => c.sortField3).ToList();

person Jon Crowell    schedule 11.01.2012    source источник


Ответы (2)


Взгляните на http://tomasp.net/articles/dynamic-linq-queries.aspx для руководства по созданию динамических запросов LinQ во время выполнения. Это должно быть то, что вы ищете.

person ChrisiPK    schedule 11.01.2012
comment
Спасибо, Криси. Я взгляну. - person Jon Crowell; 12.01.2012
comment
Я прочитал пост Томаса. Я также просмотрел Запись Скотта Гатри (от 2008 г.) на сайте dynamic linq. Мне не понравилось, что обе эти тропы кажутся мертвыми. У Томаса есть ссылка на его проект CodePlex, который был в альфа-версии в 2007 году, и с тех пор его никто не трогал. К счастью, решение цепочки переменного количества .OrderBy работает для меня. - person Jon Crowell; 12.01.2012

Я решил это, объединив операторы .OrderBy в цикле ForEach. .OrderBy добавляется к моему запросу Linq для каждого критерия сортировки, выбранного пользователем. Обернув свой список в IQueryable, я могу видеть запрос Linq по мере его создания.

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();
        }

Результирующий запрос:

query = {System.Collections.Generic
        .List`1[CustomerMaster]
        .OrderBy(c => c.LName)
        .OrderBy(c => c.State)}
person Jon Crowell    schedule 12.01.2012