Ben
Ben

Reputation: 183

Combine list of parents with list of children

Is there a way using Linq to combine a list of parent objects with a list of children objects so the parent list includes the children with the same ids?

I have a list of parents with no children populated and a separate list of children and want to combine them so the list of parents has the children included with the appropriate parent.

public class Parent
{
    public int Id { get; set; }
    public virtual List<Children> Children { get; set; }
}

public class Children
{
    public int Id { get; set; }
    public int ParentId { get; set; }
}

Upvotes: 0

Views: 2324

Answers (2)

Tim Rogers
Tim Rogers

Reputation: 21723

If I understand correctly you have two lists as follows:

List<Parent> parents;
List<Children> children;

You can then join the parents with the children, to create new Parent objects that have the children attached:

var newParents = parents.GroupJoin(
     children, 
     parent => parent.Id, 
     child => child.ParentId, 
     (parent, children) => new Parent { Id = parent.Id, Children = children.ToList() });

Upvotes: 4

If your list of parents already exists, you don't want to do this entirely in LINQ. We'll use LINQ to group the children with siblings, then loop over that conventionally and assign to the parents' Children properties. If there's enough parents for the lookup to be an efficiency issue, you should put them in a dictionary.

foreach (var g in children.GroupBy(ch => ch.ParentId))
{
    //  Use Single() rather than FirstOrDefault() if orphans are forbidden.
    //  It will throw an exception if no match is found. 
    var parent = parents.FirstOrDefault(p => p.Id == g.Key);

    if (parent != null)
    {
        parent.Children = g.ToList();
    }
}

The legitimate pure-LINQ option, as Tim notes, is to create new Parent objects. Nothing wrong with that. What you don't want to do is write a LINQ query that alters the input objects. That generally ends in tears. The above pattern gets used in code where I work because we have large POCO classes with many properties and no existing need for copy constructors.

Upvotes: 1

Related Questions