{
public static class TreeExtensions
{
private static IEnumerable<TreeNode<TEntity>> CreateHierarchy<TEntity, TProperty>(IEnumerable<TEntity> items, TEntity parentItem,
Func<TEntity, TProperty> idProperty, Func<TEntity, TProperty> parentIdProperty, int level, Func<TEntity, TProperty> orderBy) where TEntity : class
{
items = items.OrderBy(orderBy);
IEnumerable<TEntity> childs;
if (parentItem == null)
childs = items.Where(i => parentIdProperty(i).Equals(default(TProperty)));
else
childs = items.Where(i => parentIdProperty(i).Equals(idProperty(parentItem)));
if (childs.Any())
{
level++;
foreach (var item in childs)
{
yield return new TreeNode<TEntity>
{
Entity = item,
Children = CreateHierarchy<TEntity, TProperty>(items, item, idProperty, parentIdProperty, level, orderBy).ToList(),
Level = level
};
}
}
}
/// <summary>
/// LINQ IEnumerable AsHierachy() extension method
/// </summary>
/// <typeparam name=”TEntity”>Entity class</typeparam>
/// <typeparam name=”TProperty”>Property of entity class</typeparam>
/// <param name=”items”>Flat collection of entities</param>
/// <param name=”idProperty”>Reference to Id/Key of entity</param>
/// <param name=”parentIdProperty”>Reference to parent Id/Key</param>
/// <returns>Hierarchical structure of entities</returns>
public static IEnumerable<TreeNode<TEntity>> AsHierarchy<TEntity, TProperty>(this IEnumerable<TEntity> items, Func<TEntity, TProperty> idProperty, Func<TEntity, TProperty> parentIdProperty, Func<TEntity, TProperty> orderBy) where TEntity : class
{
return CreateHierarchy(items, default(TEntity), idProperty, parentIdProperty, 0, orderBy);
}
}
}
public class TreeNode<T>
{
public TreeNode()
{
Children = new List<TreeNode<T>>();
}
public T Entity { get; set; }
public int Level { get; set; }
public List<TreeNode<T>> Children { get; set; }
}