猿问

根据属性值从嵌套对象中提取对象并投影到新类

我有以下嵌套输入类


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

}

对于每个具有 IsSelected = true 属性的 MessageViewModel 实例,在这种情况下最好的解决方案是什么?这可以使用 AutoMapper 实现吗?


编辑:


假设我有以下对象:


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

        };

我想遍历它并仅提取和映射 IsSelected 等于 true 的 MessageViewModels。


BIG阳
浏览 120回答 3
3回答

斯蒂芬大帝

解决了:使用以下代码:&nbsp;public static class TraversalHelper{&nbsp; &nbsp; public static void TraverseAndExecute<T>(this T composite, Func<T, IEnumerable<T>> selectChildren, Action<T> action)&nbsp; &nbsp; &nbsp; &nbsp; where T : class&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; action.Invoke(composite);&nbsp; &nbsp; &nbsp; &nbsp; composite.TraverseAndExecute(selectChildren, action, new List<T> { composite });&nbsp; &nbsp; }&nbsp; &nbsp; private static void TraverseAndExecute<T>(this T composite, Func<T, IEnumerable<T>> selectChildren, Action<T> action, IList<T> invokedComponents)&nbsp; &nbsp; &nbsp; &nbsp; where T : class&nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; invokedComponents = invokedComponents ?? new List<T>();&nbsp; &nbsp; &nbsp; &nbsp; var components = selectChildren(composite) ?? new T[] { };&nbsp; &nbsp; &nbsp; &nbsp; foreach (var component in components)&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if (!invokedComponents.Contains(component))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; action.Invoke(component);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; invokedComponents.Add(component);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; component.TraverseAndExecute(selectChildren, action, invokedComponents);&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; else&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; }}我设法迭代我的分层对象:&nbsp;var vm = new MessageViewModel&nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Messages = new List<MessageViewModel> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new MessageViewModel {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IsSelected = true,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Messages = new List<MessageViewModel> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new MessageViewModel {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; IsSelected = true,&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Messages = new List<MessageViewModel> {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new MessageViewModel { },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new MessageViewModel { },&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; new MessageViewModel { } } } } } }&nbsp; &nbsp; &nbsp; &nbsp; };&nbsp; &nbsp; &nbsp; &nbsp; var results = new List<DestinationClass>();&nbsp; &nbsp; &nbsp; &nbsp; vm.TraverseAndExecute(_ => _.Messages, _ => {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(_.IsSelected == true)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; {&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; results.Add(new DestinationClass { Subject = _.Subject });&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }&nbsp; &nbsp; &nbsp; &nbsp; });

小怪兽爱吃肉

由于您的类是嵌套层次结构,因此您需要一个扩展方法。具有更多 LINQ 特征的一个将是:public static IEnumerable<T> Flatten<T>(this T current, Func<T, IEnumerable<T>> childrenFn) {&nbsp; &nbsp; var working = new Stack<T>();&nbsp; &nbsp; working.Push(current);&nbsp; &nbsp; while (working.Count > 0) {&nbsp; &nbsp; &nbsp; &nbsp; current = working.Pop();&nbsp; &nbsp; &nbsp; &nbsp; yield return current;&nbsp; &nbsp; &nbsp; &nbsp; if (childrenFn(current) != null)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; foreach (var child in childrenFn(current))&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; working.Push(child);&nbsp; &nbsp; }}这需要一个父对象和一个函数,该函数从父对象返回子对象列表并返回所有扁平化的对象。现在您可以使用它来生成您的答案:var ans = vm.Flatten(mvm => mvm.Messages)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Where(mvm => mvm.IsSelected)&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; .Select(mvm => new DestinationClass() { Subject = mvm.Subject });

临摹微笑

在这种情况下,我将使用 Message ViewModel 的 IEnumerable 作为 DestinationClass 中的构造函数参数。然后,您可以使用 System.Linq 遍历 MessageViewModels 集合并选择条件为真的每个模型并将其转换为 DestinationClass 的 IEnumerable。这只是您解决此问题的一种方法。如果您可以向我们提供有关您的解决方案架构的更多详细信息,我们将更容易为您提供支持。问候 EnvyIT
随时随地看视频慕课网APP
我要回答