Search code examples
c#linqcollectionsienumerableilist

Applying child collections to matching parents in the parent collection


I have a method which will map the child collections to appropriate parents in the parent collection

 public static void ApplyParentChild<TParent, TChild, TId>(
           this IEnumerable<TParent> parents, IEnumerable<TChild> children,
           Func<TParent, TId> id, Func<TChild, TId> parentId,
           Action<TParent, TChild> action
          )
    {
        var lookup = parents.ToDictionary(id);
        foreach (var child in children)
        {
            TParent parent;
            if (lookup.TryGetValue(parentId(child), out parent))
                action(parent, child);
        }
    }

&This woks if I call the method as below ( project having list of phases in it)

projects.ApplyParentChild(phases, p => p.ProjectId, c => c.ProjectId, (p, c) => p.ProjectPhases.Add(c));

But I often get a situation where i have a phase having project reference in it . so that time I call it as

phases.ApplyParentChild(projects, p => p.ProjectId, c => c.ProjectId, (p, c) => p.project=c);

this fails . this is because parents.ToDictionary(id) fails to get unique identifiers and returns the error as "An item with the same key has already been added."

How do I handle this problem ? I am not a linq master . Can anyone help me out ?


Solution

  • Since Project has a one to many relationship with Phases, you have to always use Project as the parent. Just change the action:

    projects.ApplyParentChild(
        phases,
        p => p.ProjectId,
        c => c.ProjectId,
        (p, c) => c.project = p);