Я пишу поставщика LINQ для иерархического источника данных. Мне проще всего разработать свой API, написав примеры, показывающие, как я хочу его использовать, а затем кодирование для поддержки этих случаев использования.
Одна вещь, с которой я столкнулся, - это простой/многоразовый/элегантный способ выражения "глубокого запроса" или рекурсии в операторе LINQ. Другими словами, какой лучший способ отличить:
from item in immediate-descendants-of-current-node where ... select item
против
from item in all-descendants-of-current-node where ... select item
(Edit: обратите внимание, что ни один из приведенных выше примеров не обязательно отражает структуру запроса, который я хочу. Меня интересует любой хороший способ выразить рекурсию/глубину)
Обратите внимание. Я не спрашиваю, как реализовать такого провайдера, или как написать IQueryable или IEnumerable таким образом, чтобы разрешить рекурсию. Я задаю вопрос с точки зрения лица, пишущего запрос LINQ и использующего моего провайдера, - что интуитивно понятно для них, чтобы выразить, хотят ли они рекурсивно или нет?
Структура данных похожа на типичную файловую систему: папка может содержать коллекцию подпапок, а папка также может содержать коллекцию элементов. Таким образом, myFolder.Folders представляет все папки, которые являются непосредственными дочерними элементами myFolder, а myFolder.Items содержит все элементы сразу в myFolder. Вот базовый пример сайта hierachy, очень похожий на файловую систему с папками и страницами:
(F)Products
(F)Light Trucks
(F)Z150
(I)Pictures
(I)Specs
(I)Reviews
(F)Z250
(I)Pictures
(I)Specs
(I)Reviews
(F)Z350
(I)Pictures
(I)Specs
(I)Reviews
(I)Splash Page
(F)Heavy Trucks
(F)Consumer Vehicles
(I)Overview
Если я пишу:
from item in lightTrucks.Items where item.Title == "Pictures" select item
Каков самый интуитивный способ выразить намерение, что запрос получит все предметы под Light Trucks или только ближайшие? Меньше-навязчивый способ с наименьшим трением для различения двух намерений?
Цель My # 1 - превратить этого поставщика LINQ в других разработчиков, которые имеют среднее представление о LINQ и позволяют им писать как рекурсивные, так и запросы списка, не давая им учебника по написанию рекурсивных лямбда. Учитывая использование, которое выглядит хорошо, я могу указать провайдера на это.
Дополнительные разъяснения: (я действительно сосать об этом!). Этот поставщик LINQ относится к внешней системе, это не просто ходящий объектный граф, а в этом конкретном случае рекурсивный выражение фактически переводится в любую реальную рекурсивную деятельность под капотом. Просто нужно различать "глубокий" запрос и "мелкий".
Итак, как вы думаете, лучший способ выразить это? Или есть стандартный способ выразить это, что я пропустил?