【问题标题】:How to do Linq GroupJoin on self to fill children/parent properties?如何对自己进行 Linq GroupJoin 以填充子/父属性?
【发布时间】:2011-12-22 15:31:46
【问题描述】:

我有以下课程

public class OrderItem
{
    public Guid ID { get; set; }
    public Guid? ParentID { get; set; }
    public IEnumerable<OrderItem> Children { get; set; }
    public OrderItem Parent { get; set; }
}

我最初将它们全部从数据库中获取并放入数组中。

OrderItem[] arrOrderItems = ctx.Database.SqlQuery<OrderItem>(orderItemsQuery).ToArray();

现在我想链接这些类,以便我的基本数组仍然包含所有项目,但每个项目都有其导航属性集(孩子、父母)。

是否有任何提供此功能的 Linq 函数?

我最初的想法是先做一个 GroupJoin 来填充孩子,然后再做一个 Join 来填充父母。我在下面有我的示例 GroupJoin 代码。我不知道如何让 groupjoin 返回父对象。它试图返回 IEnumerable >

arrOrderItems = arrOrderItems.GroupJoin(arrOrderItems, 
                                        x => x.ID, x => x.ParentID, 
                                        (parent, children) => 
                                        parent.Children = children);

有什么想法吗?

编辑:

我只是想找到一种更好(更快)的方法来做到这一点

foreach(OrderItem item in arrOrderItems)
{
    if (item.ParentID.HasValue)
        item.ParentOrderItem = arrOrderItems.Where(x => x.ID == item.ParentID.Value).FirstOrDefault();

    item.Children = arrOrderItems.Where(x => x.ParentID.HasValue && x.ParentID.Value == item.ID).ToArray();
}

【问题讨论】:

  • 您使用的是实体框架还是 LINQ to SQL?
  • 不,有一个自定义 SQL 查询,只是告诉 .sqlquery 用数据填充什么对象。

标签: c# linq join


【解决方案1】:

不确定在 GroupJoin 中分配 children 数组是一种很好的做法,但要完成您想要的,您只需将代码更改为:

  var result = arrOrderItems.GroupJoin( arrOrderItems,
                                        x => x.ID, x => x.ParentID,
                                        ( parent, children ) => { parent.Children = children; return parent; } );

如果您想重新分配 arrOrderItems,您还必须添加 .ToArray() 之类的

  arrOrderItems = arrOrderItems.GroupJoin( arrOrderItems,
                                           x => x.ID, x => x.ParentID,
                                           ( parent, children ) => { parent.Children = children; return parent; } ).ToArray();

我认为更好的做法是分离出实际执行分配的代码

foreach ( var pair in arrOrderItems.GroupJoin( arrOrderItems,
                                               x => x.ID, x => x.ParentID,
                                               ( parent, children ) => Tuple.Create( parent, children ) ) ) {

  var parent = pair.Item1;
  var children = pair.Item2;

  parent.Children = children;
  foreach ( var child in children )
    child.Parent = parent;
  }

【讨论】:

  • +1 从我在我的问题 (9:20) 中发布的循环到您的 (0:20) 在 72,000 项数组上的循环执行时间得到了惊人的改进。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多