将父级和子级列表组合到一个嵌套的父级列表中

时间:2016-12-22 21:20:39

标签: linq

我有两个列表,一个父列表(父母)和一个子列表(孩子),子列表中有一个parentId。

List<Parent> parents
List<Child> children

我正在尝试将两个列表组合成一个父列表,每个父对象都有一个子列表。我现在循环遍历父列表并根据parentId填充每个父对象中的Children列表,但我想知道是否有更快的方法使用LINQ执行此操作。

foreach (var parent in parents)
{
   parent.Children = children.Where(c=>c.ParentId == parent.Id).ToList();
}

有什么建议吗?

3 个答案:

答案 0 :(得分:2)

您可以使用Join,并结合GroupBy

var parentChildrenQry =
    from parent in parents
    join child in children on parent.Id equals child.ParentId
    group child by parent;

foreach(var grp in parentChildrenQry) {
    grp.Key.Children = grp.ToList();
}

或者同时使用GroupJoin的一个声明:

var parentChildrenQry =
    parents.GroupJoin(children, parent.Id, child.ParentId, new { (parent, childGrp) => new { Parent = parent, Children = childGrp.ToList() } );

foreach(var grp in parentChildrenQry) {
    grp.Parent.Children = grp.Children;
}

答案 1 :(得分:1)

从表现的角度来看,你的foreach没有错。

如果你的代码足够可读,那么就没有必要让你的代码变得更加流畅。

如果您的馆藏非常庞大,从性能角度来看,如果您首先按父ID对孩子进行分组并按父ID排序,并将其附加到已排序的父母,则可能效率最高。

答案 2 :(得分:0)

我知道这是一个老问题,但我想分享我的经验

对我来说,我在数据库中有很多记录,因此性能非常重要,我可以用另一种方式对其进行创建,并使结果快3倍左右。一键获取所有数据,然后将结果放入模型中。

我有带有菜单和菜肴表的餐厅数据库。

首先,这些是将处理所选数据且与数据库模型不同的类模型

public class Menu
{
    public Menu()
    {
        Dishes = new List<Dish>();
    }

    public long ID { get; set; }
    public string Name { get; set; }
    public string ImagePath { get; set; }
    public List<Dish> Dishes { get; set; }
}

public class Dish
{
    public long ID { get; set; }
    public string Name { get; set; }
    public string PicturePath { get; set; }
    public double Price { get; set; }
}

这是Linq查询

var all = (from m in contexts.RestMenus
            join d in contexts.ResDishes on m.Id equals d.MenuID
            select new
            {
                Menu = new Menu()
                {
                    ID = m.MenuID,
                    Name = m.Name,
                    ImagePath = m.ImageURL
                },
                Dish = new Dish()
                {
                    ID = d.ItemID,
                    Name = d.Name,
                    PicturePath = d.PicturePath,
                    Price = d.DefaultPrice
                }
            }).ToList();

和foreach循环以整理数据

List<Menu> menus = new List<Menu>();
foreach (var r in all)
{
    Menu m = menus.Find(x => x == r.Menu);
    if (m == null)
    {
        menus.Add(r.Menu);
        m = r.Menu;
    }
    m.Dishes.Add(r.Dish);
}