LINQ Select Statement для сопоставления сущности с помощью рекурсии - PullRequest
1 голос
/ 15 марта 2019

У меня есть Category Сущность, которая имеет коллекцию дочерних категорий и допускает нулевую ссылку на 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; } 
}

У меня есть сценарий, в котором мне нужно «скопировать» существующую сущность (Zone), которая имеет ссылки на Categories. В операторе select мне нужно отобразить существующие категории и их дочерние элементы в новую запись категории, чтобы при сохранении новых категорий содержалась ссылка на новую скопированную Zone.

Проблема, с которой я столкнулся, - это метод рекурсии, который будет циклически проходить по текущей категории LINQ select (x) и создавать новые записи категории для каждого из дочерних элементов и т. Д.

Вот соответствующая часть текущего оператора "копирования", который у меня есть. Должен ли я вызвать Where на Categories, которые являются верхним уровнем, то есть не имеют ParentId, а затем использовать рекурсивный метод для детей?

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

Ответы [ 2 ]

2 голосов
/ 15 марта 2019

Возможно, вы ищете такой конструктор копирования?

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...
}

Использование:

var deepCopied = zone.Categories.Select(c => new Category(c));
0 голосов
/ 15 марта 2019

Используйте рекурсивный метод выбора, например, так:

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;
        }
    }
}

Затем выполните реализацию:

var lookup = _dbContext.Categories.ToLookup(x => x.ParentId);
var parents = lookup[null].SelectRecursive(x => lookup[x.Id]).Where(c => c.ParentId == null).ToList();
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...