Как оптимизировать атрибуты повторного запроса запроса Linq to Xml? - PullRequest
2 голосов
/ 19 марта 2009

Учитывая следующий фрагмент XML:

<root>
  <sheetData>
    <row r="1" />
    <row r="2" />
    <row r="3" />
    <row r="4" />
    <row r="5" />
    <row r="6" />
    <row r="7" />
  </sheetData>
</root>

Который может быть создан с помощью следующего кода:

XElement testElement = new XElement("root",
    new XElement("sheetData",
        new XElement("row",
            new XAttribute("r", 1)),
        new XElement("row",
            new XAttribute("r", 2)),
        new XElement("row",
            new XAttribute("r", 3)),
        new XElement("row",
            new XAttribute("r", 4)),
        new XElement("row",
            new XAttribute("r", 5)),
        new XElement("row",
            new XAttribute("r", 6)),
        new XElement("row",
            new XAttribute("r", 7))));

Это лучший способ найти строку, в которой атрибут r равен 2? Это работает, но я повторяю пункт Где в выберите утверждение, и мне интересно, есть ли лучший способ и более эффективный метод.

int rowNumber = 2;

XElement rowElement = testElement
    .Descendants("sheetData")
    .Where<XElement>(item => item.Descendants("row")
                                  .Where<XElement>(i => i.Attribute("r").Value == rowNumber.ToString())
                                  .FirstOrDefault<XElement>() != null)
    .Select<XElement, XElement>(item => item.Descendants("row")
                                  .Where<XElement>(i => i.Attribute("r").Value == rowNumber.ToString())
                                  .FirstOrDefault<XElement>())
    .FirstOrDefault<XElement>();

В целом, как определить, оптимизирован ли запрос Linq to Xml?

Ответы [ 3 ]

4 голосов
/ 19 марта 2009

Лучший способ это:

var row = testElement
   .XPathSelectElements("sheetData/row[@r='2']")
   .FirstOrDefault();

Чистый запрос LINQ, который не повторяет вызов Where:

var row = testElement
    .Descendants("sheetData")
    .Descendants("row")
    .Where(x => x.Attribute("r").Value == "2")
    .FirstOrDefault();
1 голос
/ 19 марта 2009
//if sheetData appears multiple times
    XElement rowElement = testElement
        .Descendants("sheetData")
        .SelectMany(s=>s.Descendats("row))
        .Where(i=>i.Attribute("r").Value == rowNumber.ToString());
//if sheetData appears once
    XElement rowElement = testElement
        .Element("sheetData")
        .Descendants("row))
        .Where(i=>i.Attribute("r").Value == rowNumber.ToString());
0 голосов
/ 19 марта 2009

Не является ли предложение Select в вашем коде избыточным? Где возвращает IEnumerable<XElement> уже. Я думаю

var row = testElements.Descendents("row").Where(e => (int)e.Attribute("r") == rowNumber).SingleOrDefault();

должен делать то, что вы хотите

...