1

I have a Category Entity that has a collection of child Categories and a nullable reference to a Parent Category.

public class Category
{
    public int Id { get; set; }
    public string Name { get; set; }
    public int? ParentId { get; set; }

    public Category Parent { get; set; }
    public ICollection<Category> Children { get; set; } 
}

I have the scenario where I need to "copy" an existing entity (Zone) which has references to Categories. Within the select statement I need to map the existing categories and their children to a new Category record so that when I save the new categories will hold a reference to the new copied Zone.

The problem I'm having is a recursion method that will loop through the current LINQ select (x) Category and create new Category records for each of its children s children etc.

Here is the relevant part of the current "copy" select statement I have. Do I call Where on Categories that are top level i.e don't have a ParentId and then use a recursive method for the children?

Categories = zone.Categories.Where(y => !y.ParentId.HasValue).Select(x => new Category
{
     Children = WHAT DO I PUT IN HERE
     Name = x.Name,
}).ToList()

2 Answers 2

2

Are you perhaps looking for a copy constructor like this?

public class Category 
{
    // Copy constructor, recursively called for each child.
    public Category(Category other)
    {
        Id = other.Id;
        Name = other.Name;
        ParentId = other.ParentId;
        Parent = other.Parent;
        // Use this copy constructor for each child too:
        Children = other.Children.Select(c => new Category(c)).ToList();
    }
    // We probably want the default constructor too.
    public Category() { }

    // Your Props...
}

Usage:

var deepCopied = zone.Categories.Select(c => new Category(c));
Sign up to request clarification or add additional context in comments.

1 Comment

I had already came up with a solution as this was posted. Its similar to what I have so I will make it as the answer. Thanks!
0

Use a select recursive method like so:

public static class EnumerableExtensions
{
    public static IEnumerable<T> SelectRecursive<T>(this IEnumerable<T> source, Func<T, IEnumerable<T>> selector)
    {
        foreach (var parent in source)
        {
            yield return parent;

            var children = selector(parent);
            foreach (var child in SelectRecursive(children, selector))
                yield return child;
        }
    }
}

Then do an implementation:

var lookup = _dbContext.Categories.ToLookup(x => x.ParentId);
var parents = lookup[null].SelectRecursive(x => lookup[x.Id]).Where(c => c.ParentId == null).ToList();

1 Comment

I've already read this solution on a different post and it doesn't meet the requirement I need.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.