如何使用linq从分层数据结构中投影新类型

时间:2010-02-22 15:08:31

标签: c# linq collections

我们有一个名为Group的类,它包含一组问题它还包含一组组(即我们有一组潜在的嵌套)。

用XML表示这可能是这样的:

<group id="Group1">
  <questions>
      <question id="questions11"/>
  </questions>
  <groups>
    <group id="group12">
      <questions>
          <question id="question121"/>
      </questions>
      <groups>
        <group id ="group121">
          <questions>
             <question id="question1211"/>
          </questions>
        </group>
        <group id ="group122">
          <questions>
            <question id="question1221"/>
          </questions>
        </group>        
      </groups>
    </group>
    <group id="group13">
      <questions>
          <question id="question131"/>
      </questions>
    </group>
  </groups>
</group>

我实际上已经简化了结构,为简洁起见,我在每个组中省略了一些我希望包含在投影中的属性。

我想要做的是塑造一种新类型,包括这里的层次结构和一些属性,但不包括其他一些和问题。

我完全坚持要在linq中执行此操作。我看了一下SelectMany,但这不是我想要的。

TIA

2 个答案:

答案 0 :(得分:0)

您需要创建一个递归函数,将<group>元素转换为Group个实例,并为子<group>元素调用自身。

答案 1 :(得分:0)

嗯......我不确定你会使用哪些对象,但如果 来自xml,你可能会尝试类似的东西:

    public class Group
    {
        public string Id { get; set; }
        IEnumerable<Question> Questions { get; set; }
        IEnumerable<Group> Groups { get; set; }

        public static IEnumerable<Group> Extract(XElement groupElement)
        {
            var groups = new List<Group>();
            var group = new Group{ Id = groupElement.Attribute("id").Value};
            groups.Add(group);

            // Extract questions.
            var questionsSubRoot = groupElement.Element("questions");
            if (questionsSubRoot != null)
                group.Questions = Question.Extract(questionsSubRoot);

            // Extract subgroups.
            var groupsElement = groupElement.Element("groups");
            if (groupsElement != null)
                group.Groups = groupsElement.Elements("group").SelectMany(elem => Group.Extract(elem));

            return groups;
        }
    }

和你的问题课......

    public class Question
    {
        public string Id { get; set; }

        public static IEnumerable<Question> Extract(XElement questionsElement)
        {
            return questionsElement.Elements().Select(elem => new Question { Id = elem.Attribute("id").Value });
        }
    }

你会称之为......

var xDoc = XDocument.Parse(xml);
var groups = Group.Extract(xDoc.Element("group"));