У меня недавно была эта проблема, и я наткнулся на этот вопрос после того, как нашел простой способ достижения результатов. Я предоставил редактирование ответа Крэйга, предоставив 4-й метод, но власти решили, что это должен быть другой ответ. Это нормально со мной:)
Мой оригинальный вопрос / ответ можно найти здесь.
Это работает, пока ваши элементы в таблице все знают, к какому дереву они принадлежат (что в вашем случае выглядит так: t.ID
). Тем не менее, не ясно, какие сущности у вас действительно есть в игре, но даже если у вас есть более одного, вы должны иметь FK в сущности Children
, если это не TreeSet
В основном, просто не используйте Include()
:
var query = from t in context.TreeSet
where t.ID == id
select t;
// if TreeSet.Children is a different entity:
var query = from c in context.TreeSetChildren
// guessing the FK property TreeSetID
where c.TreeSetID == id
select c;
Это вернет ВСЕ предметы для дерева и поместит их все в корень коллекции. На этом этапе ваш набор результатов будет выглядеть так:
-- Item1
-- Item2
-- Item3
-- Item4
-- Item5
-- Item2
-- Item3
-- Item5
Поскольку вы, вероятно, хотите, чтобы ваши сущности выходили из EF только иерархически, это не то, что вы хотите, верно?
.. затем исключить потомков, присутствующих на корневом уровне:
К счастью, поскольку у вас есть свойства навигации в вашей модели, коллекции дочерних сущностей будут по-прежнему заполняться, как вы можете видеть на иллюстрации вышеупомянутого набора результатов. Если вручную выполнить итерацию по результирующему набору с циклом foreach()
и добавить эти корневые элементы в new List<TreeSet>()
, теперь у вас будет список с корневыми элементами и всеми потомками, правильно вложенными.
Если ваши деревья становятся большими и производительность вызывает беспокойство, вы можете отсортировать возвращаемый набор ASCENDING по ParentID
(это Nullable
, верно?), Чтобы все корневые элементы были первыми. Повторяйте и добавляйте, как раньше, но прерывайте цикл, как только вы доберетесь до цикла, который не равен нулю.
var subset = query
// execute the query against the DB
.ToList()
// filter out non-root-items
.Where(x => !x.ParentId.HasValue);
А теперь subset
будет выглядеть так:
-- Item1
-- Item2
-- Item3
-- Item4
-- Item5
О решениях Крейга: