简体   繁体   中英

LINQ query to group parent and child elements

I'm currently working on a .NET 4.7 application. 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. Each ChildLocation can have several ChildLocations itself again.

I need to sort the data from the following structure. My unsorted data is a List<LinkParentChildViewModel> LinksParentChild , and looks like this:

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.

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.

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 .

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

var result = GetHierarchy(LinksParentChild, 8);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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