你最初的问题有些不同。我认为每个载体都应该持有其所有后代的列表。现在看来,你只想持有所有直接子代。那很简单:
c.Children = carrierList.Where(child => child.ParentCarrierId == c.CarrierId).ToList()
如果您希望将其作为LINQ查询,则必须创建Carrier
的新实例:
List<Carrier> rootCarriers = carrierList
.Select(c => new Carrier {
CarrierId = c.CarrierId,
Name = c.Name,
Descrition = c.Descrition,
ParentCarrierId = c.ParentCarrierId,
Children = carrierList
.Where(child => child.ParentCarrierId == c.CarrierId)
.ToList()
})
.Where(c => !c.ParentCarrierId.HasValue)
.ToList();
那个查询还会移除所有没有父级的非根载体。
下面展示了两种不同属性的方法,
Children
和
Descendants
,后者甚至返回孙子等更多后代。
public class Carrier
{
public List<Carrier> Descendants { get; set; }
public List<Carrier> Children { get; set; }
public static IEnumerable<Carrier> TraverseDescendants(IEnumerable<Carrier> allCarriers, Carrier rootCarrier)
{
Queue<Carrier> queue = new Queue<Carrier>();
var children = allCarriers.Where(c => c.ParentCarrierId == rootCarrier.CarrierId);
foreach (Carrier c in children)
queue.Enqueue(c);
while (queue.Count > 0)
{
Carrier child = queue.Dequeue();
yield return child;
var grandchildren = allCarriers.Where(c => c.ParentCarrierId == child.CarrierId);
foreach (Carrier c in grandchildren)
queue.Enqueue(c);
}
}
}
使用TraverseDescendents
,您可以初始化类中的List<Carrier> Descendents
。 Children
列表是一个简单的LINQ查询:
foreach (Carrier c in carrierList)
{
c.Descendants = Carrier.TraverseDescendants(carrierList, c).ToList();
c.Children = carrierList.Where(child => child.ParentCarrierId == c.CarrierId).ToList();
}