У меня похожая ситуация. Мне не удалось решить это напрямую с помощью LINQ / EF. Вместо этого я решил создать представление базы данных с использованием рекурсивных общих табличных выражений, как указано здесь . Я сделал пользовательскую функцию, которая перекрестно применяет всех родителей к дочернему элементу (или наоборот), затем представление, которое использует эту пользовательскую функцию, которую я импортировал в контекст моего объекта EF.
(отказ от ответственности: упрощенный код, я на самом деле не проверял это)
У меня есть две таблицы: MyTable (содержащая все элементы) и MyParentChildTable, содержащие отношение ChildId, ParentId
Затем я определил следующий udf:
CREATE FUNCTION dbo.fn_getsupertree(@childid AS INT)
RETURNS @TREE TABLE
(
ChildId INT NOT NULL
,ParentId INT NULL
,Level INT NOT NULL
)
AS
BEGIN
WITH Parent_Tree(ChildId, ParentId)
AS
(
-- Anchor Member (AM)
SELECT ChildId, ParentId, 0
FROM MyParentChildTable
WHERE ChildId = @childid
UNION all
-- Recursive Member (RM)
SELECT info.ChildId, info.ParentId, tree.[Level]+1
FROM MyParentChildTable AS info
JOIN Parent_Tree AS tree
ON info.ChildId = tree.ParentId
)
INSERT INTO @TREE
SELECT * FROM Parent_Tree;
RETURN
END
и следующий вид:
CREATE VIEW VwSuperTree AS (
SELECT tree.*
FROM MyTable
CROSS APPLY fn_getsupertree(MyTable.Id) as tree
)
GO
Это дает мне каждого ребенка, всех родителей с их «уровнем дерева» (у прямого родителя есть уровень 1, у родителя родителя есть уровень 2 и т. Д.). С этой точки зрения легко запросить элемент с самым высоким уровнем. Я просто импортировал представление в моем контексте EF, чтобы иметь возможность запрашивать его с помощью LINQ.