Сортировка по не работает с Concat () в LINQ - PullRequest
16 голосов
/ 08 августа 2011

Использование VB.net и следующий оператор LINQ.Я подозреваю, что «Order by» не работает с Concat().Я хочу перечислить текущий элемент, который есть у пользователя, а затем перечислить больше доступных элементов в порядке возрастания.Итак, сначала я выбираю текущий элемент из БД, а затем выбираю следующие доступные элементы по порядку.LINQ игнорирует порядок по утверждению и сортировку по PK (который является itemID). Я проверил список сразу после выполнения оператора.Когда я разбиваю заявление и делаю их отдельно, они работают, как и предполагалось.Любые идеи, предложения или комментарии.Спасибо, PM

(From items In myDatabase.ItemAssignments _
 Where items.BuildingID = buildingID _
 And items.ResidentID = ResidentID _
 Select items).Concat(From moreitems In myDatabase.ItemAssignments _
                      Where moreitems.occupied = 0 _
                      And moreitems.BuildingID = buildingID _
                      Order by moreitems.Floor, moreitems.ItemNumber _
                      Select moreitems)

1 Ответ

15 голосов
/ 08 августа 2011

Concat действительно игнорирует предложение order by, когда речь идет о LINQ to SQL. Это можно проверить из сгенерированного SQL, если вы используете LINQPad или настроите свойство DataContext.Log .

Один из способов справиться с этим - ввести фиктивное значение через анонимный тип, чтобы помочь с упорядочением. Для ясности я разделил запросы ниже, хотя тот же подход возможен с использованием синтаксиса запросов, с которого вы начинали до тех пор, пока вам не потребуется указать порядок.

Dim firstQuery = From items In myDatabase.ItemAssignments _
                 Where items.BuildingID = buildingID _
                 And items.ResidentID = ResidentID _
                 Select New With { .Row = items, .Order = 1 }
Dim secondQuery = From moreitems In myDatabase.ItemAssignments _
                  Where moreitems.occupied = 0 _
                  And moreitems.BuildingID = buildingID _
                  Select New With { .Row = moreitems, .Order = 2 }

Dim query = firstQuery.Concat(secondQuery) _
                      .OrderBy(Function(o) o.Order) _
                      .ThenBy(Function(o) o.Row.Floor) _
                      .ThenBy(Function(o) o.Row.ItemNumber) _
                      .Select(Function(o) o.Row)

Другим менее желательным вариантом является вызов метода AsEnumerable для одного из запросов, который будет извлекать результаты из базы данных. В зависимости от количества задействованных элементов и необходимости дальнейшей фильтрации это может отрицательно сказаться на производительности.

Чтобы использовать этот подход, измените первую часть исходного запроса:

From items In myDatabase.ItemAssignments.AsEnumerable() ...

Порядок второй части будет работать так, как задумано, и сгенерированный SQL будет отражать столько же.

...