2013-07-19 54 views
0

的我現在有一堆的配置文件,我需要加載到IOrderedEnumerable我目前的做法看起來像這樣:而不是使Items等於items.OrderBy(x => x.Attribute("ID").Value)Collection添加到結束IOrderedEnumerable

foreach (var item in configFiles) 
{ 
    XDocument myxml = XDocument.Load(item); 
    var items = myxml.Root.Elements("Item"); 
    Items = items.OrderBy(x => x.Attribute("ID").Value); 
    ItemsLength += Items.Count();    
} 

的問題是,我想將它加入到當前存在的IOrderedEnumerable的末尾,這樣每次加載新的XDocument並從中獲取所有元素時,我都不會覆蓋它。我將如何做到這一點?

編輯:我知道如果我改變這ItemsLength += Items.Count();將不再正常工作。這是我自己改變的事情。

+0

什麼是*終極*來這裏的目的 - 你試圖獲得由'ID'下令所有項目,或只能通過訂購ID * *在他們的文件*。目前還不清楚你真正想要達到的目標。 (我懷疑你確實需要一個'IOrderedEnumerable' - 這就是OrderBy的返回結果,之後你會怎麼做?我期望一個'IEnumerable'就足夠了。) –

+0

只在ID文件中按ID排序。 – DanteTheEgregore

+0

我會建議將所有物品放在一起,然後在最後訂購一次。如果您有一些屬性代表您可以按順序排列的文檔,然後只需爲該ID添加一個「ThenBy」。 – Servy

回答

2

你可以聲明整件事:

Items = configFiles.Select((item, index) => new { Doc = XDocument.Parse(item), 
                Index = index }) 
        .SelectMany(pair => pair.Doc.Root.Elements("Item") 
              .Select(x => new { Item = x, 
                   Index = pair.Index })) 
        .OrderBy(pair => pair.Index) 
        .ThenBy(pair => (string) pair.Attribute("ID")) 
        .Select(pair => pair.Item); 

這基本上找到所有元素,但記得每次在其中配置

或者,只需要創建一個List<XElement>並添加每個項目的內容:

var items = new List<XElement>(); 
foreach (var item in configFiles) 
{ 
    items.AddRange(XDocument.Parse(item) 
          .Root.Elements("Item") 
          .OrderBy(x => (string) x.Attribute("ID"))); 
} 
Items = items; 

在某些方面,這是不太優雅,但它可能更容易理解:)

+1

您的查詢需要從保存在索引上的匿名對象中最後選擇項目。 – Servy

+0

@Servy:良好的捕捉 - 修復,謝謝。 –

1

如果你可以改變ItemsIEnumerable而非IOrderedEnumerable類型的,你可以使用Concat

Items = Items.Concat(items.OrderBy(x => x.Attribute("ID").Value)); 

這將保持自己的文檔內ID排序的項。

請注意,在迴路中使用Concat可能會損害性能。你會被關閉,宣佈ItemsIList更好,並呼籲ToList在每次迭代的結尾:

Items.AddRange(items.OrderBy(x => x.Attribute("ID").Value)); 
+2

如果您打算將'Items'列爲列表,您最好使用AddRange添加新文檔的項目,而不是每次都創建一個新列表。 – Servy

+0

@Servy這是一個很棒的評論,謝謝! – dasblinkenlight