Добро пожаловать в форум, Guest  >>   Войти | Регистрация | Поиск | Правила | В избранное | Подписаться
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Новый топик    Ответить
 LINQ XML, быстрый поиск элемента по имени и атрибуту  [new]
Shakill
Member

Откуда: мск
Сообщений: 1880
здравствуйте
заполняю дерево, перед добавлением листа надо найти для него родительский узел (по имени и значению атрибута), если такой узел не найден, то его тоже надо создать. важна скорость, что посоветуете?

пробовал такие варианты (XElement skillNode - искомый/добавляемый родительский узел, XElement treeRoot - корень дерева):

1. через xpath, способ самый красивый, но очень тормозной
            xpath = "skill[@Id='" + sklId + "']";
            skillNode = treeRoot.XPathSelectElement(xpath);
            if (skillNode == null) { // узел не найден - добавляем
                skillNode = new XElement("skill",
                    new XAttribute("Id", sklId),
                    new XAttribute("Name", skd.Name));
                treeRoot.Add(skillNode);                
            }
           
            skillNode.Add(... )  // добавляем лист

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

            try {
                
                skillNode = treeRoot.Elements("skill").Single(skl => skl.Attribute("Id").Value == sklId);
            }
            catch { // не нашли - добавляем
                skillNode = new XElement("skill",
                    new XAttribute("Id", sklId),
                    new XAttribute("Name", skd.Name));
                treeRoot.Add(skillNode);                
            }

            skillNode.Add(... )  // добавляем лист

3. через селект, скорость как у первого способа, так еще и выглядит громоздко

            var els =
                from tt in treeRoot.Elements("skills")
                where tt.Attribute("Id").Value == sklId
                select tt;

            if (els.Count() > 0)
                skillNode = els.First(); // если нашли
            else { // если не нашли 
                skillNode = new XElement("skill",
                    new XAttribute("Id", sklId),
                    new XAttribute("Name", skd.Name));
                treeRoot.Add(skillNode);
            };

            skillNode.Add(... )  // добавляем лист
26 июн 09, 12:52    [7347469]     Ответить | Цитировать Сообщить модератору
 Re: LINQ XML, быстрый поиск элемента по имени и атрибуту  [new]
Shakill
Member

Откуда: мск
Сообщений: 1880
4. ручной перебор, еще немного быстрее чем вариант №2. но недостаточно

            IEnumerable<XElement> skills = treeRoot.Elements("skill");
            skillNode = null;
                                    
            foreach (XElement skill in skills) {
                if (skill.Attribute("Id").Value == sklId) {
                    skillNode = skill;
                    break;
                }
            };


            if (skillNode == null) { // добавляем узел
                skillNode = new XElement("skill",
                    new XAttribute("Id", sklId),
                    new XAttribute("Name", skd.Name));
                treeRoot.Add(skillNode); 
            }

            skillNode.Add (... )  // добавляем лист
26 июн 09, 16:50    [7349419]     Ответить | Цитировать Сообщить модератору
Все форумы / ADO.NET, LINQ, Entity Framework, NHibernate, DAL, ORM Ответить