質問

I'm trying to understand a concept here:

From an object structure like

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

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

Assuming a fully populated parent object, I would like to use Linq to Xml to obtain the following Xml output:

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

How do I unwind the original object nested to obtain this mapping list?

EDIT

Example with a parent such as :

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

I am expecting 3 mappings :

<Mapping ID='Parent1' ChildID='Child1' />
<Mapping ID='Parent1' ChildID='Child2' />
<Mapping ID='Parent1' ChildID='Child3' />
役に立ちましたか?

解決

EDIT

The following code will flatten the hierarchy :

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);

Output :

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

Here's an example on how to achieve it :

Note : this won't work, it will generate an exception saying 'Duplicate attribute'

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);

This one will because it will use the overload of Select that uses the index of the current object :

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);

Result : not what you've been expecting, right ?

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

Why I've used this overload ?

Because parent has a list of childrens, while the first code would work with one children it would not with many of them.

Conclusion :

Not sure about what you're trying to achieve,

Why don't you just keep the structure of your objects as it is currently ?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top