2013-07-19 50 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