Заказ не работает с Concat() в LINQ

Использование VB.net и следующего оператора LINQ. Я подозреваю, что "Заказ по" не работает с Concat(). Я хочу перечислить текущий элемент, который пользователь имеет, а затем перечислить более доступные элементы в порядке поступления. Поэтому сначала я выбираю текущий элемент из db, а затем выбираю следующие доступные предметы по порядку. 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

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 будет отражать столько же.