Reputation: 1593
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()
Upvotes: 1
Views: 200
Reputation: 727
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();
Upvotes: 0
Reputation: 1739
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));
Upvotes: 2