Подтвердить что ты не робот

IQueryable порядок по двум или более свойствам

В настоящее время я заказываю список настраиваемых объектов с использованием метода IQueryable OrderBy следующим образом:

mylist.AsQueryable().OrderBy("PropertyName");

Теперь я ищу сортировку более чем одного свойства. Есть ли способ сделать это?

Спасибо, Яннис

4b9b3361

Ответ 1

OrderBy(i => i.PropertyName).ThenBy(i => i.AnotherProperty)

В OrderBy и ThenBy вы должны предоставить функцию keySelector, которая выбирает ключ для сортировки с объекта. Поэтому, если вы знаете имя свойства только во время выполнения, вы можете сделать такую ​​функцию с помощью Reflection как:

var propertyInfo = i.GetType().GetProperty("PropertyName"); 
var sortedList = myList.OrderBy(i => propertyInfo.GetValue(i, null)) 

Но это будет медленнее, а затем прямой доступ к свойству. Также вы можете "скомпилировать" такую ​​функцию "на лету" с помощью Linq.Expressions, и она будет работать быстрее, чем отражение, но это не очень просто. Или вы можете использовать CollectionViewSource и их функции сортировки в WPF.

И не забывайте, что OrderBy() возвращает отсортированную перечислимую и не сортирует ваш существующий List inplace. В вашем примере вы не сохранили отсортированный список в переменной.

Ответ 2

Вы можете использовать .ThenBy:

var result = mylist
    .AsQueryable()
    .OrderBy(x => x.PropertyName)
    .ThenBy(x => x.SomeOtherProperty);

Ответ 3

Возможно, вы захотите использовать метод расширения ThenBy, чтобы иметь возможность сортировки по нескольким полям

 return myList.AsQueryable().OrderBy(m=>m.Property1).ThenBy(m => m.Property2);

Если вам нужен динамический Linq, посмотрите LinqKit. Недавно я реализовал динамическую библиотеку Microsoft Linq из здесь и смог отсортировать по двум полям, используя строку.

Потрясающие вещи! Не уверен, будет ли это в .NET 5 или нет.

Ответ 4

Как предлагали другие, вы можете использовать "ThenBy". Если вы хотите преобразовать строку в другое значение перед ее использованием, это тоже возможно, например...

    var sortedSystemTestResultsList = systemTestResultsList.OrderBy(s =>
    {
        DateTime dt;
        if (!DateTime.TryParse(s.testPointCompletedDate, out dt)) return DateTime.MaxValue;
        return dt;
    }).ThenBy(s =>
    {
        Int32 tpID;
        if (!Int32.TryParse(s.testRunResultID, out tpID)) return Int32.MaxValue;
        return tpID;
    });