2013-11-18 1 views
1

Мне нужно заказать дочерние элементы XML-элемента. Детские элементы содержат несколько элементов, которые не являются обязательными.Перечисляемый OrderBy используется для заказа коллекции несколькими необязательными полями

То, что я пытался до сих пор:

var orderedElements = parent.Elements("ChildElement") 
    .OrderBy(child => child.Element("Field1").Value.ToString()) 
    .ThenBy(child => child.Element("Field2").Value.ToString()) 
    .ToList(); 

Проблема заключается в том, что Field2 не является обязательным элементом ChildElement и я, очевидно, получить нулевой ссылочный исключение, если Field2 нет в ChildElement. Можно ли изменить аргумент ThenBy(), чтобы заказать ChildElements после Field2, только если существует в ChildElements?

+1

Почему бы вам не сделать метод расширения, называемый ValueOrDefault (string elementName) '? –

ответ

2

Просто проверьте, если поле element существует:

var orderedElements = parent.Elements("ChildElement") 
    .OrderBy(child => child.Element("Field1").Value) 
    .ThenBy(child => child.Element("Field2") != null ? child.Element("Field2").Value : string.Empty) 
    .ToList(); 

(Кстати, вам не нужно вызывать ToString() на Value, так как это уже строка)

+0

Пробовал с if, но не мог заставить его работать. Благодаря! – vicch

+1

Это всегда будет упорядочиваться по 'Field2', он просто будет использовать пустую строку для тех детей, где это значение недоступно. –

0

Если вы хотите удалить заказ по Field2, когда любого дочернего элемента имеет отсутствующий дочерний элемент Field2, изменить аргумент метода невозможно, но вы можете сделать это:

var orderedElements = parent 
    .Elements("ChildElement") 
    .All(child2 => child2.Element("Field2") != null) ? 
     parent.Elements("ChildElement") 
      .OrderBy(child => child.Element("Field1").Value) 
      .ThenBy(child => child.Element("Field2").Value) 
      .ToList() : 
     parent.Elements("ChildElement") 
      .OrderBy(child => child.Element("Field1").Value) 
      .ToList(); 

Если вы просто хотите, чтобы игнорировать недостающие Field2 детей и до сих пор применяется порядок, основанный на ChildElements элементов, которые имеют Field2, вы можете использовать подход @Thomas Levesques-х годов, с упоминанием о том, что элементы с отсутствующей Field2 будет сначала появятся в упорядоченном списке.

+1

Спасибо за ответ, но мне нужно применить заказ по Field2, даже если он отсутствует в некоторых дочерних элементах. – vicch