I have the following class
public class OrderItem
{
public Guid ID { get; set; }
public Guid? ParentID { get; set; }
public IEnumerable<OrderItem> Children { get; set; }
public OrderItem Parent { get; set; }
}
I initially fetch them all from a database and into an array.
OrderItem[] arrOrderItems = ctx.Database.SqlQuery<OrderItem>(orderItemsQuery).ToArray();
Now I want to link up the classes so that my base array still contains ALL the items, but each item has its navigational properties set (Children, Parent).
Are there any Linq functions that provide this functionality?
My inital thought was doing a GroupJoin to fill the children and then a Join to fill the parents. I have my sample GroupJoin code below. I could not figure out how to have the groupjoin return the parent object. It is trying to return IEnumerable < IEnumerable < OrderItem > >
arrOrderItems = arrOrderItems.GroupJoin(arrOrderItems,
x => x.ID, x => x.ParentID,
(parent, children) =>
parent.Children = children);
Any thoughts?
Edit :
I just want to find a better (faster) way to do this
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();
}
Not sure that assigning the children array inside the GroupJoin is a very good practice but to accomplish what you want you'd just change the code to:
var result = arrOrderItems.GroupJoin( arrOrderItems,
x => x.ID, x => x.ParentID,
( parent, children ) => { parent.Children = children; return parent; } );
If you want to reassign arrOrderItems, you'd also have to add a .ToArray() like
arrOrderItems = arrOrderItems.GroupJoin( arrOrderItems,
x => x.ID, x => x.ParentID,
( parent, children ) => { parent.Children = children; return parent; } ).ToArray();
I think a better practice would be to separate out the bit of code actually doing the assignments like so
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;
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With