为了账号安全,请及时绑定邮箱和手机立即绑定

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

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

C#
BIG阳 2021-06-25 18:32:58
我有以下嵌套输入类 //InputClasspublic class MessageViewModel {    public bool IsSelected { get; set; }    public string Subject { get; set; }    public DateTime CreationDate { get; set; }    public List<MessageViewModel> Messages { get; set; }}我想创建以下类型的新实例: //Target Classpublic 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。
查看完整描述

3 回答

?
斯蒂芬大帝

TA贡献1827条经验 获得超8个赞

解决了:


使用以下代码:


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

            }

        });


查看完整回答
反对 回复 2021-06-27
?
小怪兽爱吃肉

TA贡献1852条经验 获得超1个赞

由于您的类是嵌套层次结构,因此您需要一个扩展方法。


具有更多 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 });


查看完整回答
反对 回复 2021-06-27
?
临摹微笑

TA贡献1982条经验 获得超2个赞

在这种情况下,我将使用 Message ViewModel 的 IEnumerable 作为 DestinationClass 中的构造函数参数。然后,您可以使用 System.Linq 遍历 MessageViewModels 集合并选择条件为真的每个模型并将其转换为 DestinationClass 的 IEnumerable。

这只是您解决此问题的一种方法。如果您可以向我们提供有关您的解决方案架构的更多详细信息,我们将更容易为您提供支持。问候 EnvyIT


查看完整回答
反对 回复 2021-06-27
  • 3 回答
  • 0 关注
  • 104 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信