【发布时间】:2014-11-11 13:07:30
【问题描述】:
我有一个邻接模型列表来存储如下层次结构。表结构类似于Nothwind 数据库中的employees 表。示例如下。
员工 ID 1 报告给员工 ID 2
员工 ID 3 报告给员工 ID 2
员工 ID 4 报告给员工 ID 2
员工 ID 5 报告给员工 ID 3
员工 ID 6 报告给员工 ID 4
员工 ID 7 报告给员工 ID 5
员工 ID 8 报告给员工 ID 7。
我想知道叶子节点员工的列表,即对其他员工来说不是“老板”的员工。在上面的示例中,它们是 1、8 和 6。我尝试编写一个 LINQ 扩展来获取所有叶节点,如下所示。
public static IEnumerable<TEntity> SelectDeep<TEntity, TProperty>(
this IEnumerable<TEntity> allItems,
Func<TEntity, TProperty> idProperty,
Func<TEntity, TProperty> parentIdProperty,
object rootItemId)
{
IEnumerable<TEntity> leve11Data = LevelDeep(allItems, default(TEntity), idProperty, parentIdProperty, rootItemId);
IEnumerable<TProperty> leafOnly = leve11Data.Select(i => idProperty(i)).Except(leve11Data.Select(i => parentIdProperty(i)));
IEnumerable<TEntity> childItemsOnly = allItems.Where(i => leafOnly.Contains(idProperty(i)));
return childItemsOnly;
}
public static IEnumerable<TEntity> LevelDeep<TEntity, TProperty>(this IEnumerable<TEntity>allItems,
TEntity parentItem,
Func<TEntity, TProperty> idProperty,
Func<TEntity, TProperty> parentIdProperty,
object rootItemId)
{
IEnumerable<TEntity> childs;
if (rootItemId != null)
{
childs = allItems.Where(i => parentIdProperty(i).Equals(rootItemId));
}
else
{
if (parentItem == null)
{
childs = allItems.Where(i => parentIdProperty(i).Equals(default(TProperty)));
}
else
{
childs = allItems.Where(i => parentIdProperty(i).Equals(idProperty(parentItem)));
}
}
if (childs.Count() > 0)
{
foreach (TEntity item in childs)
{
yield return item;
foreach (TEntity subItem in LevelDeep(allItems, item, idProperty, parentIdProperty, null))
{
yield return subItem;
}
}
}
}
我称之为:
(from listEntry in myList.SelectDeep(e => e.child_part_id, e => e.parent_part_id, 100).ToList()
但不幸的是,我的扩展方法进入了无限循环,我无法弄清楚为什么.. 有人可以帮忙吗..
【问题讨论】:
-
为什么你的 LevelDeep 中有 item 和 rootItemId?这不应该基本上是一样的吗?