Извлечение объектов из вложенного объекта на основе значения свойства и проектирование в новый класс - PullRequest
0 голосов
/ 22 мая 2018

У меня есть следующий вложенный класс ввода

 //InputClass
public class MessageViewModel 
{
    public bool IsSelected { get; set; }

    public string Subject { get; set; }

    public DateTime CreationDate { get; set; }
    public List<MessageViewModel> Messages { get; set; }
}

, и я хочу создать новый экземпляр следующего типа:

 //Target Class
public class DestinationClass
{
    public string Subject { get; set; }
}

для каждого экземпляра MessageViewModel, который имеет свойство IsSelected= true Какое решение является лучшим в этом случае?Может ли это быть достигнуто с помощью AutoMapper?

EDIT:

позволяет предположить, что у меня есть следующий объект:

var vm = new MessageViewModel
        {
            Messages = new List<MessageViewModel> {
                            new MessageViewModel {
                                IsSelected = true,
                                    Messages = new List<MessageViewModel> {
                                            new MessageViewModel { IsSelected = true,
                                                                    Messages = new List<MessageViewModel> { new MessageViewModel { },
                                                                                                            new MessageViewModel { },
                                                                        new MessageViewModel { } } } } } }
        };

Я хотел бы пройти его и извлекать и отображать толькоMessageViewModels, для которого IsSelected равно true.

решено:

с использованием следующего кода:

 public static class TraversalHelper
{
    public static void TraverseAndExecute<T>(this T composite, Func<T, IEnumerable<T>> selectChildren, Action<T> action)
        where T : class
    {
        action.Invoke(composite);
        composite.TraverseAndExecute(selectChildren, action, new List<T> { composite });
    }

    private static void TraverseAndExecute<T>(this T composite, Func<T, IEnumerable<T>> selectChildren, Action<T> action, IList<T> invokedComponents)
        where T : class
    {
        invokedComponents = invokedComponents ?? new List<T>();
        var components = selectChildren(composite) ?? new T[] { };
        foreach (var component in components)
        {
            if (!invokedComponents.Contains(component))
            {
                action.Invoke(component);
                invokedComponents.Add(component);
                component.TraverseAndExecute(selectChildren, action, invokedComponents);
            }
            else
            {

            }
        }
    }
}

Мне удалось выполнить итерацию по моему иерархическому объекту:

 var vm = new MessageViewModel
        {
            Messages = new List<MessageViewModel> {
                            new MessageViewModel {
                                IsSelected = true,
                                    Messages = new List<MessageViewModel> {
                                            new MessageViewModel {
                                                IsSelected = true,
                                                Messages = new List<MessageViewModel> {
                                                    new MessageViewModel { },
                                                    new MessageViewModel { },
                                                    new MessageViewModel { } } } } } }
        };

        var results = new List<DestinationClass>();

        vm.TraverseAndExecute(_ => _.Messages, _ => {
            if(_.IsSelected == true)
            {
                results.Add(new DestinationClass { Subject = _.Subject });
            }
        });

Ответы [ 2 ]

0 голосов
/ 22 мая 2018

В этом случае я бы использовал IEnumerable Message ViewModel в качестве параметра конструктора в DestinationClass.Затем вы можете перебрать коллекцию MessageViewModels с помощью System.Linq и выбрать каждую модель, в которой выполняется условие, и преобразовать ее в IEnumerable класса DestinationClass.

Это только один из способов решения этой проблемы.Если бы вы могли предоставить нам более подробную информацию об архитектуре ваших решений, нам было бы проще оказать вам поддержку.Привет, зависть

0 голосов
/ 22 мая 2018

Так как ваш класс является вложенной иерархией, вам нужен метод расширения.

Один с большим количеством характеристик LINQ будет:

public static IEnumerable<T> Flatten<T>(this T current, Func<T, IEnumerable<T>> childrenFn) {
    var working = new Stack<T>();
    working.Push(current);

    while (working.Count > 0) {
        current = working.Pop();
        yield return current;

        if (childrenFn(current) != null)
            foreach (var child in childrenFn(current))
                working.Push(child);
    }
}

Это принимает родительский объект и функцию, которая возвращаетсписок дочерних объектов от родителя и возвращает все сплющенные объекты.

Теперь вы можете использовать это, чтобы получить свой ответ:

var ans = vm.Flatten(mvm => mvm.Messages)
            .Where(mvm => mvm.IsSelected)
            .Select(mvm => new DestinationClass() { Subject = mvm.Subject });
...