Сортировать сущность по нескольким дочерним значениям в EF Core - PullRequest
1 голос
/ 28 апреля 2020

Итак, как можно go отсортировать сущности на основе составного значения нескольких дочерних элементов? Вот пример модели:

public class Product
{
  public int ProductId { get; set; }
  public string Name { get; set; }
  public string ProductGroup { get; set; }
  public ICollection<Option> Options { get; set; }
}

public class Option
{
  public int OptionId { get; set; }
  public int ProductId { get; set; }
  public Product Product { get; set; }
  public string Name { get; set; }
  public int NamePosition { get; set; }
  public string Value { get; set; }
  public int ValuePosition { get; set; }
}

И пример данных, которые выглядят следующим образом (предположим, что мы не можем контролировать порядок, в котором добавляются продукты или опции, поэтому первичные ключи бесполезны для заказа) :

insert into Product (Name, ProductGroup)
select 'Long, Thin Red Drapes', 'Red Drapes' -- product id 1
union all
select 'Short, Thin Red Drapes', 'Red Drapes' -- product id 2
union all
select 'Long, Wide Red Drapes', 'Red Drapes' -- product id 3
union all
select 'Short, Wide Red Drapes', 'Red Drapes' -- product id 4
union all
select 'Long, Thin White Drapes', 'White Drapes' -- product id 5
union all
select 'Short, Thin White Drapes', 'White Drapes' -- product id 6
union all
select 'Long, Wide White Drapes', 'White Drapes' -- product id 7
union all
select 'Short, Wide White Drapes', 'White Drapes' -- product id 8
go

insert into Options (ProductId, Name, NamePosition, Value, ValuePosition)
select 1, 'Length', 1, '84 inches', 2
union all
select 1, 'Width', 2, '25 inches', 1
union all
select 2, 'Length', 1, '64 inches', 1
union all
select 2, 'Width', 2, '25 inches', 1
union all
select 3, 'Length', 1, '84 inches', 2
union all
select 3, 'Width', 2, '42 inches', 2
union all
select 4, 'Length', 1, '64 inches', 1
union all
select 4, 'Width', 2, '42 inches', 2
union all
select 5, 'Length', 1, '84 inches', 2
union all
select 5, 'Width', 2, '25 inches', 1
union all
select 6, 'Length', 1, '64 inches', 1
union all
select 6, 'Width', 2, '25 inches', 1
union all
select 7, 'Length', 1, '84 inches', 2
union all
select 7, 'Width', 2, '42 inches', 2
union all
select 8, 'Length', 1, '64 inches', 1
union all
select 8, 'Width', 2, '42 inches', 2
go

Мы хотели бы отсортировать товары по их значениям длины, а затем по их значениям ширины, чтобы отсортированный список ProductId для «Красных полос» был бы: {2, 4, 1, 3} .

Кажется, что здесь есть решение OrderBy, ThenBy, использующее отсортированные позиции имен в качестве ординалов или что-то в этом роде, но я не могу его найти. Пока что единственное решение, которое я могу обернуть вокруг себя, - это создать в контроллере специальный трюк сортировки, который бы создавал составное значение, основанное на всех дочерних элементах, следующим образом:

ProductId 1 = Long, Thin Red Drapes = Length:2, Width:1 = Composite "21"
ProductId 2 = Short, Thin Red Drapes = Length:1, Width:1 = Composite "11"
ProductId 3 = Long, Wide Red Drapes = Length:2, Width:2 = Composite "22"
ProductId 4 = Short, Wide Red Drapes = Length:1, Width:2 = Composite "12"

Затем сортировка по этому составному значению мы получаем {"11", "12", "21", "22"} или желаемую последовательность {2, 4, 1, 3}.

Но это ужасно неловко , и сломался бы, если бы продукт сопровождался 10+ возможными значениями параметров.

Этот запрос помог бы, кроме дублирования элементов по количеству параметров:

select i.Name, o.NamePosition, o.ValuePosition
from SaleableItem i
join SaleableOption o on o.SaleableItemId = i.SaleableItemId
where i.ProductGroup = 'Red Drapes'
order by o.NamePosition, o.ValuePosition

Спасибо за любые комментарии или предложения!

...