2014-04-09 46 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