简体   繁体   English

LINQ 查询以对父元素和子元素进行分组

[英]LINQ query to group parent and child elements

I'm currently working on a .NET 4.7 application.我目前正在开发一个 .NET 4.7 应用程序。 I need to create a tree structure out of unsorted data.我需要用未排序的数据创建一个树结构。

The final tree structure looks like this:最终的树结构如下所示:

public class LocationViewModel
{
    public int Id { get; set; }
    public string Code { get; set; }
    public List<LocationViewModel> ChildLocations { get; set; }
}

One Parent LocationViewModel can have several ChildLocations.一个 Parent LocationViewModel 可以有多个 ChildLocations。 Each ChildLocation can have several ChildLocations itself again.每个 ChildLocation 本身又可以有多个 ChildLocations。

I need to sort the data from the following structure.我需要从以下结构中对数据进行排序。 My unsorted data is a List<LinkParentChildViewModel> LinksParentChild , and looks like this:我的未排序数据是List<LinkParentChildViewModel> LinksParentChild ,如下所示:

public class LinkParentChildViewModel
{
    public Location Parent { get; set; }
    public LocationLink Child { get; set; }
}

public class Location
{
   public int Id { get; set; }
   public string Code { get; set; }
}

public class LocationLink
{
   public int ParentLocationId { get; set; }
   public int ChildLocationId { get; set; }
}

First I have a List<Location> Locations , which contains all the locations.首先,我有一个List<Location> Locations ,其中包含所有位置。

Then I'm getting a List<LinkParentChildViewModel> LinksParentChild , the entries are all mixed up - thus a Parent can be a child and a child can be a parent.然后我得到一个List<LinkParentChildViewModel> LinksParentChild ,条目都混淆了 - 因此 Parent 可以是孩子,而孩子可以是父母。

var LinksParentChild = new List<LinkParentChildViewModel>
{
    new LinkParentChildViewModel
    {
        Parent = new Location
        {
            Id = 8,
            Code = "ParLoc1",
        },
        Child = new LocationLink
        {
            ChildLocationId = 4,
            ParentLocationId = null
        }
    },
    new LinkParentChildViewModel
    {
        Parent = new Location
        {
            Id = 4,
            Code = "Loc1",
        },
        Child = new LocationLink
        {
            ChildLocationId = 6,
            ParentLocationId = 8
        }
    },
    new LinkParentChildViewModel
    {
        Parent = new Location
        {
            Id = 6,
            Code = "ChildLoc1",
        },
        Child = new LocationLink
        {
            ChildLocationId = null,
            ParentLocationId = 4
        }
    },
    new LinkParentChildViewModel
    {
        Parent = new Location
        {
            Id = 10,
            Code = "LeftLoc1",
        },
        Child = new LocationLink
        {
            ChildLocationId = 11,
            ParentLocationId = 4
        }
    },
    new LinkParentChildViewModel
    {
        Parent = new Location
        {
            Id = 11,
            Code = "LeftChildLoc1",
        },
        Child = new LocationLink
        {
            ChildLocationId = null,
            ParentLocationId = 10
        }
    }
};

I need to write a LINQ query to group all nodes from my data into a List<LocationViewModel> result .我需要编写一个 LINQ 查询来将数据中的所有节点分组到List<LocationViewModel> result

var result = LinksParentChild.GroupBy(x => x.Parent.Id).Select(x => new LocationViewModel
{
    Id = x.First().Parent.Id,
    Code = x.First().Parent.Code,
    ChildLocations = new List<LocationViewModel>
    {
        // ... I'm stuck unfortunately, somehow i need to query and group all locations
    }
}).ToList();

I tried, but unfortunately I'm stuck:我试过了,但不幸的是我被卡住了:

  • I need to select all Locations like a tree structure我需要像树结构一样选择所有位置

Do you know how to solve this issue?你知道如何解决这个问题吗?

Thanks a lot!非常感谢!

The result looks like this:结果如下所示:

var result = new List<LocationViewModel>
{
    new LocationViewModel
    {
        Id = 8,
        Code = "ParLoc1",
        ChildLocations = new List<LocationViewModel>
        {
            new LocationViewModel
            {
                Id = 4,
                Code = "Loc1",
                ChildLocations = new List<LocationViewModel>
                {
                    new LocationViewModel
                    {
                        Id = 6,
                        Code = "ChildLoc1"
                    },
                    new LocationViewModel
                    {
                        Id = 10,
                        Code = "LeftLoc1",
                        ChildLocations = new List<LocationViewModel>
                        {
                            new LocationViewModel
                            {
                                Id = 11,
                                Code = "LeftChildLoc1"
                            }
                        }
                    }
                }
            }
        }
    }
};

you can try with Recursion你可以试试递归

public static List<LocationViewModel> GetHierarchy(List<LinkParentChildViewModel> linkParentChildViewModels, int parentId)
{
    return linkParentChildViewModels.Where(x => x.Parent.Id == parentId).Select(x => new LocationViewModel
    {
        Id = x.Parent.Id,
        Code = x.Parent.Code,
        ChildLocations = GetHierarchy(linkParentChildViewModels, x.Child.ChildLocationId)
    }).ToList();
}

Call this from Main method从 Main 方法调用它

var result = GetHierarchy(LinksParentChild, 8);

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM