I have an XDocument with a fragment that resembles:
<Data> <Row Id="0" ParentId="-1"> <!-- stuff --> </Row> <Row Id="1" ParentId="0"> <!-- stuff --> </Row> <Row Id="2" ParentId="0"> <!-- stuff --> </Row> <Row Id="3" ParentId="-1"> <!-- stuff --> </Row> <Row Id="4" ParentId="3"> <!-- stuff --> </Row> </Data>
Assume nesting is limited to the example above.
I want to create a data structure – IDictionary<Parent, List<Child>>. I can’t seem to get anything to join correctly. What I have to this point is:
// get lists of data nodes
List<XElement> pRows = xData.Elements(XName.Get("Row"))
.Where(e => e.Attribute(XParentId).Value == "-1")
.Select(e => e)
.ToList();
List<XElement> cRows = xData.Elements(XName.Get("Row"))
.Where(e => e.Attribute(XParentId).Value != "-1")
.Select(e => e)
.ToList();
var dataSets = pRows.GroupJoin(cRows,
p => p,
c => c.Attribute(XParentId).Value,
(p, children) => new {
ParentID = p.Attribute(XId).Value,
Children = children.Select(c => c)
});
The compiler is complaining:
The type arguments for method
‘System.Linq.Enumerable.GroupJoin(System.Collections.Generic.IEnumerable,
System.Collections.Generic.IEnumerable,
System.Func, System.Func,
System.Func,TResult>)’
cannot be inferred from the usage. Try specifying the type arguments
explicitly.
I followed a sample from MSDN using the GroupJoin. I didn’t want to use 2 lists – I’d prefer to use a single list of List<XElement> containing all the rows.
I think the 2 list approach is cleaner, except I would avoid calling
ToList()until the final step or when the list is really needed. You could turn it into one statement, but it would be long and harder to follow.To fix your query, you need to change the outer key selector for
pRowsfromp => ptop => p.Attribute(XId).Value, which is the actual ID. Currently it selects the entire element, which cannot be compared toc => c.Attribute(XParentId).Valuesince they are different types. The updated query would be:To avoid using 2 lists you could modify the query above and replace
pRowsandcRowswith their respective queries, but that makes it long and harder on the eyes. In this particular case I prefer expressing theGroupJoinusing query syntax since it is much easier to read than the fluent syntax:Should your real problem have more nesting, LINQ probably won’t be the ideal solution.