Используйте Linq to Query для терминальных / конечных узлов в иерархической таблице / составном шаблоне - PullRequest
3 голосов
/ 06 января 2009

У меня есть самоссылающаяся таблица с Id, CategoryName и ParentId. Это типичный сценарий иерархической таблицы категорий, которая сама может быть разделена на категории, которые, как говорят мне эксперты по БД, называется моделью смежности.

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

Легкая часть, которую я получил, это просто получение подкатегорий. Почти стыдно поставить код здесь. Но нам нравится видеть код ..

IList<Categories> subcategories = context.Where( c => c.ParentId == 1).ToList();  

Но сужение до категорий без подкатегорий меня заводит. Любая помощь будет высоко ценится.

Спасибо за помощь. Джефф

UPDATE ** Казалось бы, это работает, но если бы кто-то мог подтвердить, что это "правильно", я был бы благодарен. Итак, если я хочу листовые узлы в категории с Id = 1, я бы сделал это:

Categories.Where( c => !c.Children.Any ( d => d.ParentId == c.Id)).Where( e => e.ParentId == 1) 

«Дети» - это имя, которое Линк называет ассоциацией, ссылающейся на себя.

Ответы [ 2 ]

2 голосов
/ 06 января 2009

Ваше решение правильное, потому что метод Any() переводится в функцию sql "EXISTS ()" и !c.Children.Any ( d => d.ParentId == c.Id)) переводится в SQL-предложение, подобное NOT EXISTS (SELECT * FROM Categories WHERE ParentID = outerRef.ID)

Другой способ сделать это - использовать Count:

Categories.Where( c => c.Children.Count(d => d.ParentId == c.Id) == 0).Where( e => e.ParentId == 1)

Но обычно EXISTS () предпочтительнее, чем COUNT () в sql (по соображениям производительности), поэтому решение с Any () должно быть правильным.

0 голосов
/ 06 января 2009

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

Я не уверен, что это работает, так как мне нечего тестировать ...

   (from c in context
    join cc in context on c.id equals cc.parentid into temp
    from t in temp.DefaultIfEmpty()
    where t == null
    select c).ToList()
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...