LINQ - Выбрать все в иерархии родитель-потомок - PullRequest
3 голосов
/ 12 марта 2012

Мне было интересно, есть ли изящный способ сделать это, чтобы не использовать циклы while и т. П., Предпочтительно, чтобы они работали с Linq to Entities как единым циклом SQL, а также с Linq To Объекты.

У меня есть сущность - Forum - с которой происходят отношения родитель-ребенок. То есть Forum может (или в случае верхнего уровня может не иметь) иметь ParentForum и может иметь много ChildForums. A Forum тогда содержит много Posts.

То, что я здесь ищу, - это способ получить все Posts из дерева Forums - то есть Forum, о котором идет речь, и всех его детей, внуков и т. Д. Я не знаю заранее сколько подуровней может иметь рассматриваемый Forum.

(Примечание. Я знаю, что этот пример не обязательно является ценным вариантом использования, но одна объектная модель Форума знакома большинству людей и поэтому служит общей и доступной предпосылкой, а не моей реальной моделью предметной области. )

Ответы [ 2 ]

1 голос
/ 12 марта 2012

Я уверен, что вы можете получить несколько правильных ответов относительно запросов Linq. Я публикую это как рекомендацию, когда дело касается SQL.

У меня была похожая проблема с виртуальной файловой системой в SQL. Мне нужно было иметь возможность запрашивать файлы в папках рекурсивно - с папками, конечно, с рекурсивными отношениями родитель-потомок. Мне также нужно было, чтобы это было быстро, и я, конечно же, не хотел возвращаться к обработке на стороне клиента.

Для производительности я закончил тем, что написал хранимые процедуры и встроенные функции - к сожалению, слишком сложный, чтобы публиковать их здесь (и я мог бы получить мешок для обмена балансовой единицей!). Ключом, однако, было научиться работать с рекурсивными CTE http://msdn.microsoft.com/en-us/library/ms186243.aspx. Мне потребовалось несколько дней, чтобы понять это, но производительность невероятна (хотя их очень легко ошибиться - поэтому обратите внимание на запрос планы).

1 голос
/ 12 марта 2012

Один из возможных способов был бы в том случае, если ваши фактические таблицы данных были сохранены с использованием дерева влево / вправо (пример здесь: http://www.sitepoint.com/hierarchical-data-database-2/. Обратите внимание, что этот пример в MySQL / PHP, но реализовать его тривиально). Используя это, вы можете найти все форумы, которые находятся в пределах левого / правого значений родителей, и, учитывая, что вы можете получить все сообщения, чьи идентификаторы форумов IN эти идентификаторы форумов.

...