Определите, какие узлы дерева являются листами в ленивой загрузке WCF REST API - PullRequest
0 голосов
/ 20 января 2011

Использование : SQL Server 2008, WCF 4 REST, EF

У меня есть таблица списка смежностей, представляющая дерево

TABLE Category
(
    CatId int IDENTITY(1,1) NOT NULL PRIMARY KEY,
    ParentId int NULL,
    Name nvarchar(50) NOT NULL
)

Я создаю WCF RESTAPI, позволяющий клиенту строить дерево в режиме ленивой загрузки.Выполнить запрос, чтобы получить дочерние элементы узла (nodeid ниже), просто.Я сталкиваюсь с необходимостью определить, какие узлы являются листовыми узлами.( Примечание : я удалил всю обработку ошибок, обработку count = 0, обработку нуля и т. Д. Из приведенного ниже кода)

tree = _context.Categories
               .Where(c => c.ParentId == nodeid)
               .Select(p => new TreeNode
               {
                   id = p.CatId,
                   parentId = p.ParentId ?? -1,  // -1 = NULL in data struct
                   name = p.Name,
                   isleaf = true  // how to figure this out?
               }).ToList();

Есть идеи?Я в порядке, собираюсь в сохраненный процесс для этого запроса и подумал об использовании CTE, но я не хочу проходить через все дерево - просто получить дочерние элементы указанного узла.

РЕДАКТИРОВАТЬ (20 января, 10:40 утра) Я решил изменить схему БД, добавив битовый столбец «IsLeaf».Затем я сделал обновление, чтобы настроить IsLeaf соответственно - это означает, что мне не нужно динамически выяснять это во время выполнения.Возможно, более эффективный, но мне все еще интересно, как бы я поступил по этому поводу.Пожалуйста, сообщите.

1 Ответ

1 голос
/ 21 января 2011

В LINQ нет рекурсивных функций (пока?).Поэтому, хотя в MSSQL это несколько просто, в LINQ я бы предложил сделать следующее (псевдокод):

// These two lines is one LINQ statement
level = select all root nodes (ParentID == NULL) 
add level nodes to result 
// C# loop
while level is not empty
  // The loop body except for the assignment in the end is one LINQ statement
  next = select all nodes that have parentId in level
  for each node in next
    find parent node
    add to result with updated parent info
  // C# assignment
  level = next

Как вы можете видеть, это комбинация LINQ и C #.Также, возможно, стоит перенести содержимое таблицы локально, прежде чем делать все это.

Также вам может потребоваться обновить алгоритм, чтобы при необходимости проверить циклы.

...