using JNPF.DependencyInjection; using System.Data; using System.Reflection; namespace JNPF.Common.Security; /// /// 树形结构查询 /// 版 本:V3.2.0 /// 版 权:拓通智联科技有限公司(http://www.tuotong-tech.com) /// 作 者:JNPF开发平台组. /// [SuppressSniffer] public static class QueryTreeHelper { /// /// 递归查询. /// /// 输出模型. /// 数据源. /// 查询条件. /// 主键. /// 上级. /// public static List TreeWhere(this List data, Predicate condition, Func idSelector, Func parentIdSelector) { List locateList = data.FindAll(condition); List treeList = new List(); foreach (T entity in locateList) { treeList.Add(entity); T currentNode = entity; while (true) { string parentId = parentIdSelector(currentNode); if (parentId == null) break; T upRecord = data.Find(a => idSelector(a) == parentId); if (upRecord != null) { treeList.Add(upRecord); currentNode = upRecord; } else { break; } } } return treeList.Distinct().ToList(); } /// /// 递归查询. /// /// 数据源. /// 查询条件. /// 主键. /// 上级. /// public static DataTable TreeWhere(this DataTable data, string condition, string idSelector = "F_Id", string parentIdSelector = "F_ParentId") { DataRow[] drs = data.Select(condition); DataTable treeTable = data.Clone(); foreach (DataRow dr in drs) { treeTable.ImportRow(dr); string pId = dr[parentIdSelector].ToString(); while (true) { if (string.IsNullOrEmpty(pId) && pId == "0") break; DataRow[] pdrs = data.Select(idSelector + "='" + pId + "'"); if (pdrs.Length > 0) { treeTable.ImportRow(pdrs[0]); pId = pdrs[0][parentIdSelector].ToString(); } else { break; } } } return treeTable.DefaultView.ToTable(true); } /// /// 获取全部子节点. /// /// 输出模型. /// 数据源. /// 主键值. /// 主键. /// 上级. /// public static List TreeChildNode(this List data, string idValue, Func idSelector, Func parentIdSelector) { T thisEntity = data.Find(a => idSelector(a) == idValue); foreach (var prop in from PropertyInfo prop in thisEntity.GetType().GetProperties() where prop.Name == "ParentId" || prop.Name == "parentId" select prop) { prop.SetValue(thisEntity, "0", null); break; } List treeList = new List(); treeList.Add(thisEntity); ChildNode(data, idValue, idSelector, parentIdSelector, ref treeList); return treeList; } #region Method private static void ChildNode(this List data, string idValue, Func idSelector, Func parentIdSelector, ref List treeNodes) { List locateList = data.FindAll(a => parentIdSelector(a) == idValue); if (locateList.Count > 0) { foreach (var item in locateList) { treeNodes.Add(item); ChildNode(data, idSelector(item), idSelector, parentIdSelector, ref treeNodes); } } } #endregion }