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
}