Сортировка результатов Linq по возрастанию с использованием подвыбора и затем по убыванию - PullRequest
1 голос
/ 11 ноября 2011

Я пытаюсь обработать запрос LINQ для извлечения элементов из списка, список содержит дочерний вложенный список, который мне нужно запросить для элемента, а затем использовать полученный элемент в окончательном виде всех возвращаемых записей. запрос.

Родителем является List (Of MediaItems) - структура класса выглядит следующим образом:

MediaItems
 .ID (int)
 .Src (string)
 .Advert (bool)
 .AdOptions As List(Of AdvertOptions)
 .Counter (int)

AdvertOptions class consists of:
 .Age (int)
 .Gender (int)
 .Priority (int)

Я хочу запросить любые MediaItems, которые соответствуют следующим критериям:

.Advert = true
.Age = x (paramter in calling function)
.Gender = y (paramter in calling function)

Для этого я использую следующий запрос LINQ: (Возраст и пол являются параметрами функции)

Where(Function(s) s.Advert And s.AdOptions.Any(Function(a) a.Gender = Gender And a.Age = Age))

Теперь мне нужно отсортировать результаты на основе двух уровней сортировки:

AdOptions.Priority (в порядке убывания), затем сортировка по счетчику в порядке возрастания

Это моя неудачная попытка:

Where(Function(s) s.Advert And s.AdOptions.Any(Function(a) a.Gender = Gender And a.Age = Age)).OrderBy(Function(a) From p1 In a.AdOptions Where p1.Gender = Gender And p1.Age = Age Select p1.Priority).ThenByDescending(Function(s) s.Counter)

Моя попытка не работает, я получаю следующую ошибку:

по крайней мере на объекте должен реализовываться IComparable

Кто-нибудь может увидеть, что нужно сделать для достижения моей цели?

Ben

1 Ответ

1 голос
/ 11 ноября 2011

Читая ваш код чуть ближе, я заметил, что вы заказываете по AdOptions

Я думаю это - это то, что вы действительно хотите

Sub Demo(ByVal gender As Integer, ByVal age As Integer)

    Dim items = New List(Of MediaItem)()

    Dim matching = Function(a) a.Gender = gender And a.Age = age
    Dim ads = items.Where(Function(s) s.Advert And s.AdOptions.Any(matching))

    Dim sorted = ads _
        .OrderBy(Function(a) a.AdOptions.Where(matching).Max(Function(ao) ao.Priority)) _
        .ThenByDescending(Function(s) s.Counter)

    ' if you really wanted a sorted list of AdOptions, you'd write
    Dim optionlist = ads.OrderByDescending(Function(s) s.Counter) _
       .SelectMany(Function(a) a.AdOptions.Where(matching).OrderBy(Function(ao) ao.Priority))

    ' to combine the two previous options
    Dim adsWithOptions = ads.OrderByDescending(Function(s) s.Counter) _
       .Select(Function(a) New With { _
                  .Ad = a, _
                  .Options = a.AdOptions.Where(matching) _
                      .OrderBy(Function(ao) ao.Priority) _
            })

End Sub
...