2014-04-09 44 views
-3

我想了解这里的一个概念:拼合父/子层次

从对象结构像

class Parent 
{ 
    public string ParentID { get; set; } 
    public List<Child> Children { get; set; } 
} 

class Child 
{ 
    public string ChildID { get; set; } 
} 

假设完全填充的父对象,我想用的LINQ到XML获取以下Xml输出:

<Mappings> 
    <Mapping ID='ParentID1' ChildID='ChildID1'> 
    <Mapping ID='ParentID1' ChildID='ChildID2'> 
</Mappings> 

如何展开嵌套的原始对象以获取此映射列表?

EDIT

实施例与父如:

ParentID = 'Parent1', Children = new [] { "Child1", "Child2", "Child3" } 

我期待3个映射:

<Mapping ID='Parent1' ChildID='Child1' /> 
<Mapping ID='Parent1' ChildID='Child2' /> 
<Mapping ID='Parent1' ChildID='Child3' /> 
+0

'假设一个完全填充的父对象',如何张贴它? –

+0

我不明白你希望看到什么。这是一个概念性问题。将填充ParentID和ChildID值的实际字符串文字对解决方案来说是无关紧要的。因此,没有什么可以发布的。 – Rire1979

+0

到目前为止,您在尝试生成这种类型的文件时尝试了些什么?您具体执行哪些问题? – Servy

回答

0

EDIT

下面的代码将扁平化层级:

var list = new List<Parent> 
{ 
    new Parent 
    { 
     ParentID = "parentID1", 
     Children = new List<Child> {new Child {ChildID = "childID1"}, new Child {ChildID = "childID2"}} 
    }, 
    new Parent 
    { 
     ParentID = "parentID2", 
     Children = new List<Child> {new Child {ChildID = "childID3"}, new Child {ChildID = "childID4"}} 
    } 
}; 

IEnumerable<XElement> list1 = (from parent in list 
    from child in parent.Children 
    select 
     new XElement("Mapping", new XAttribute("ID", parent.ParentID), 
      new XAttribute("ChildID", child.ChildID))); 

string @join = string.Join(Environment.NewLine, list1); 

输出:

<Mapping ID="parentID1" ChildID="childID1" /> 
<Mapping ID="parentID1" ChildID="childID2" /> 
<Mapping ID="parentID2" ChildID="childID3" /> 
<Mapping ID="parentID2" ChildID="childID4" /> 

下面是关于如何实现它的一个例子:

注:这是不行的,它会产生一个异常说'重复属性'

List<Parent> list = new List<Parent> 
{ 
    new Parent() {ParentID = "parentID1", Children = new List<Child>() {new Child() {ChildID = "childID1"},new Child() {ChildID = "childID2"}}}, 
    new Parent() {ParentID = "parentID2", Children = new List<Child>() {new Child() {ChildID = "childID3"},new Child() {ChildID = "childID4"}}} 
    }; 
IEnumerable<string> enumerable = xElements.Select(s => s.ToString()); 


IEnumerable<XElement> xElements = list.Select(s => new XElement("Mapping", new XAttribute("ID", s.ParentID), s.Children.Select(t => new XAttribute("ChildID", t.ChildID)))); 
IEnumerable<string> enumerable = xElements.Select(s => s.ToString()); 
var @join = string.Join(Environment.NewLine, enumerable); 

这人会因为它会使用的Select使用当前对象的索引过载:

var list = new List<Parent> 
{ 
    new Parent 
    { 
     ParentID = "parentID1", 
     Children = new List<Child> {new Child {ChildID = "childID1"}, new Child {ChildID = "childID2"}} 
    }, 
    new Parent 
    { 
     ParentID = "parentID2", 
     Children = new List<Child> {new Child {ChildID = "childID3"}, new Child {ChildID = "childID4"}} 
    } 
}; 

IEnumerable<XElement> xElements = 
    list.Select(
     s => 
      new XElement("Mapping", new XAttribute("ID", s.ParentID), 
       s.Children.Select((t, u) => new XAttribute(string.Format("ChildID_{0}", u), t.ChildID)))); 
var @join = string.Join(Environment.NewLine,xElements); 

结果:不是你已经期待了吧?

<Mapping ID="parentID1" ChildID_0="childID1" ChildID_1="childID2" /> 
<Mapping ID="parentID2" ChildID_0="childID3" ChildID_1="childID4" /> 

为什么我使用这个过载?

因为父母有一个儿童的列表,而第一个代码将与一个孩子一起工作,它不会与他们中的许多人。

结论:

不知道关于你想达到什么目的,

你为什么不只是保持你的对象的结构,因为它是目前?

+0

我想从上面的对象中组织的数据获取我发布的示例XML,本质上是一个(ParentID,ChildID)映射。不幸的是,更改数据结构或XML格式不是一种选择。 – Rire1979

+0

好吧,但正如我在我的回答中解释的,保持这种结构不适用于多个孩子,或者您期望生成许多映射,如Parent1 - > Child1,Parent1 - > Child2作为输出? – Aybe

+0

有效地扁平化该层次结构并获取所有行:我在原始帖子中包含一个作为编辑的示例。 – Rire1979