使用LINQ Group By返回新的XElements

时间:2010-03-30 15:38:29

标签: c# linq .net-3.5 c#-3.0 linq-to-xml

我有以下代码,让自己感到困惑:

我有一个查询返回一组已被识别为重复的记录,然后我想为每个记录创建一个XElement。这应该在我认为的一个查询中完成,但我现在已经迷失了。

var f = (from x in MyDocument.Descendants("RECORD")
                              where itemsThatWasDuplicated.Contains((int)x.Element("DOCUMENTID"))
                              group x by x.Element("DOCUMENTID").Value into g
                              let item = g.Skip(1)  //Ignore first as that is the valid one
                              select item
                              );

var errorQuery = (from x in f 
                              let sequenceNumber = x.Element("DOCUMENTID").Value
                              let detail = "Sequence number " + sequenceNumber + " was read more than once"
                              select new XElement("ERROR",
                                          new XElement("DATETIME", time),
                                          new XElement("DETAIL", detail),
                                          new XAttribute("TYPE", "DUP"),
                                          new XElement("ID", x.Element("ID").Value)
                                          )
                             );

2 个答案:

答案 0 :(得分:2)

x,每次迭代,是元素序列(不包括第一个元素)。我怀疑你想要:

from grp in f
from x in grp
let sequenceNumber = x.Element("DOCUMENTID").Value
//...

虽然您可以根据需要将组密钥带出投影,但可以进一步简化:

    var f = (from x in MyDocument.Descendants("RECORD")
             where itemsThatWasDuplicated.Contains((int)x.Element("DOCUMENTID"))
             group x by x.Element("DOCUMENTID").Value);

    var errorQuery = (from grp in f
                      from x in grp.Skip(1)
                      let detail = "Sequence number " + grp.Key + " was read more than once"
    //...

答案 1 :(得分:0)

我已经设法将其编译并且似乎可以工作但是可能需要进行一些性能调整或者我正在做一些效率低下的事情。你觉得怎么样?

errorQuery = MyDocument.Descendants("RECORD")
                        .Where(x => itemsThatWasDuplicated.Contains((int)x.Element("DOCUMENTID")))
                        .GroupBy(a => a.Element("DOCUMENTID"), (innerID, values) => values.OrderBy(b => b.Element("ID").Value))
                        .Skip(1)
                        .SelectMany(p => p)
                        .Select(item => new XElement("ERROR",
                                          new XElement("DATETIME", time),
                                          new XElement("DETAIL",  "Sequence number " + item.Element("DOCUMENTID").Value + " was read more than once"),
                                          new XAttribute("TYPE", "DUP"),
                                          new XElement("ID", item.Element("ID").Value)
                                          ));