Си диез / Говнокод #2131 Ссылка на оригинал

0

  1. 1
  2. 2
  3. 3
  4. 4
  5. 5
  6. 6
  7. 7
  8. 8
  9. 9
  10. 10
  11. 11
var r = from t in ds.ProductTags
		where t.ProductTagID == tag
			|| t.Parent.ProductTagID == tag
			|| t.Parent.Parent.ProductTagID == tag
			|| t.Parent.Parent.Parent.ProductTagID == tag
			|| t.Parent.Parent.Parent.Parent.ProductTagID == tag
			|| t.Parent.Parent.Parent.Parent.Parent.ProductTagID == tag
			|| t.Parent.Parent.Parent.Parent.Parent.Parent.ProductTagID == tag
			|| t.Parent.Parent.Parent.Parent.Parent.Parent.Parent.ProductTagID == tag
			|| t.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.Parent.ProductTagID == tag
		select t;

Это мой код. Надоело писать рекурсивные СTE чтобы выбрать всех детишек. Спросил у кастомера можно ли ограничить вложенность. Он согласился ;).. На свою голову ;).

Запостил: Mike Chaliy Mike Chaliy, (Updated )

Комментарии (14) RSS

    • База данных, видимо, по-умному организована, через правый и левый индексы обхода дерева. Или СУБД поддерживает рекурсивную выборку. Или можно создать хранимую процедуру =]
      Ответить
      • Схема обычный ID, ParentID. Было CTE (SQL Server), там рекурсивно можно было получить всех детишек. И да это была хранимка.
        Ответить
        • Сам недавно занимался подобной хренью. Вот простой способ как это можно обойти
          http://www.rockstarapps.com/wordpress/?p=82
          Там нормально описаны выборки без вы%бонов.

          А вот псевдокод как легко создать дерево (если оно таки тебе понадобится).
          class TreeNode
          {
          void AddChild(TreeNode* child)
          void * data;
          }

          class SerializedNode
          {
          int thisId;
          int parentId;
          void * data;
          }


          TreeNode * BuildTree(SerializedNode* nodes[], int count)
          {
          hash_map<int, TreeNode *> insertedMap;
          TreeNode * root = new TreeNode();
          for (int i = 0; i != count; i++) {
          insertedMap.insert(nodes[i]->thisId, nodes[i]);
          if (0 == nodes[i]->parentId) {
          root.AddChild(nodes[i]);
          } else {
          insertedMap.find(nodes[i]->parentId).AddChild(nodes[i]);
          }
          }
          return root;
          }
          Ответить
          • Аха, суперсокое решение. Для того чтобы получить детишек, загружаем в память все данные(наприммер 10000 нод), строем дерево, а потом получаем 5 детишек. Мега.
            Ответить
            • Во-первых, это псевдокод для ВСЕГО дерева.
              Во-вторых, выборка следует быть с помощью средств СУБД. Хоть статью почитал?
              Ответить
  • ну, для неограниченной вложенности есть nested sets и прочие
    Ответить
  • Как минимум - отжег. Меня как-то больше радовало один Extension Method написать для рекурсивной выборки.
    Ответить
    • Что-то мне подсказывает, что екстеншем метод тут не поможет. Можеш код показать?
      Ответить
  • Говнище ))
    Интересно посмотреть на скрип которий линк сгенерит и пустит на сиквел.
    Ответить
      • это пиздец)
        на самом деле деревянные данные достаточно часто трабл - обычно пишу хранимую процедуру и это правильно с точки зрения как читаемости кода, так и производительности - можно написать ее 1 раз и копипастить с минимальными изменениями для всех деревьев 😉
        Ответить

Добавить комментарий

Я, guest, находясь в здравом уме и твердой памяти, торжественно заявляю:

    А не использовать ли нам bbcode?


    8