Я пишу провайдеру 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
( Редактировать: обратите внимание, что ни один из приведенных выше примеров не обязательно отражает структуру запроса, который я хочу. Меня интересует любой хороший способ выражения рекурсии / глубины )
Обратите внимание Я не спрашиваю, как реализовать такого провайдера или как написать мой IQueryable или IEnumerable таким образом, чтобы разрешить рекурсию. Я спрашиваю с точки зрения человека, пишущего запрос LINQ и использующего моего провайдера, - какой для них интуитивно понятный способ выразить, хотят ли они повторяться или нет?
Структура данных напоминает типичную файловую систему: папка может содержать коллекцию подпапок, а папка также может содержать коллекцию элементов. Таким образом, myFolder.Folders представляет все папки, которые являются непосредственными дочерними элементами myFolder, а myFolder.Items содержит все элементы непосредственно в myFolder. Вот основной пример иерархии сайтов, очень похожий на файловую систему с папками и страницами:
(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 или только непосредственные? Наименее навязчивый способ различения двух намерений с наименьшим трением?
Моя цель № 1 - предоставить этого провайдера LINQ другим разработчикам, которые в среднем понимают LINQ, и позволяют им писать как рекурсивные, так и списочные запросы, не давая им учебника по написанию рекурсивных лямбд. Учитывая использование, которое выглядит хорошо, я могу закодировать провайдера против этого.
Дополнительные пояснения: (Я действительно отстой, когда сообщаю об этом!) - Этот поставщик LINQ предназначен для внешней системы, он не просто просматривает граф объектов, а в данном конкретном случае рекурсивен выражение фактически переводится в любой реальный рекурсивный вид деятельности под капотом. Просто нужен способ различить «глубокий» запрос и «неглубокий».
Итак, что, по вашему мнению, является лучшим способом выразить это? Или есть стандартный способ выразить это, что я пропустил?